Skip to main content
gamedev.net
🔒 Locked

problems with strlen() and pointers!!

Started by styfir 6 replies 6.1k views
Original Post
styfir
styfir
Hi - The code below will basically copy one char array into another but alas I cannot achieve this as you will see.


#include<iostream>
using namespace std;


// functions prototypes //

void FillDisks(char* ch_ptr1, char* ch_ptr2, char* ch_ptr_A);



void main()
{
	char disk[50];
	char* ch_ptr_A = disk;
	
	char tempArray1[50], tempArray2[50];
	char* ch_ptr1 = tempArray1;
	char* ch_ptr2 = tempArray2;
	 
	cout << "Enter some data for array1...";
	cin >> tempArray1;
	
	cout << "\nEnter some data for array2...";
	cin>> tempArray2;

	FillDisks(ch_ptr1, ch_ptr2, ch_ptr_A);


	// print out array!! //

	for(int x=0; x<50; ++x)
	{
		cout << disk[x];
	}	
}


// Functions //

void FillDisks(char* ch_ptr1, char* ch_ptr2, char* ch_ptr_A)
{

	cout << "\n\n\nthis is in tempArray1 ... " << ch_ptr1;
	cout << endl;
	cout << "\nlength of tempArray1=" << strlen(ch_ptr1) << "\n\n";

	
	// dereferencing.............
	for(int i=0; i<strlen(ch_ptr1); i++)
	{
		*ch_ptr_A++ = *ch_ptr1++; // this is the culprit line, i think!
	}

	cout << "\n\n\nthis is in tempArray1 ... " << ch_ptr1;
	cout << endl;
	cout << "\nlength of tempArray1=" << strlen(ch_ptr1) << "\n\n";

	cout << "\n\n\n\n";


}
1. ask user for data ; only tempArray1 is being used here... 2. goto to func and print out contents of array and the length of string therein 3. copy tempArray1 to disk[]; 4. print out contents of array and the length of string therein ; again. 5. return and print out contents of newly filled array; disk[] problem is.... it only copies part of the string and I dont know why!!
Phobon
Phobon
Your problem probably lies here:
for(int i=0; i<strlen(ch_ptr1); i++) //Here you read the length of ch_ptr1	{		*ch_ptr_A++ = *ch_ptr1++; // Here you change ch_ptr1	}


Because you increment ch_ptr1 in the loop, the length of the string at ch_ptr1 becomes shorter each iteration (Because you start one character later).

It should work like this:
const size_t Length = strlen(ch_ptr1);for(int i=0; i<Length; i++) //Length doesn't change every iteration now	{		*ch_ptr_A++ = *ch_ptr1++;	}


But, seriously, why don't you use std::string ?
Evil Steve
Evil Steve
Why are you using char*'s if you're using C++? This is exactly what std::string is for...

As for the actual problem:
// dereferencing.............for(int i=0; i<strlen(ch_ptr1); i++){	*ch_ptr_A++ = *ch_ptr1++; // this is the culprit line, i think!}
You're changing the ch_ptr1 pointer every loop, and recalculating the length. You should do:
// dereferencing.............size_t nLen = strlen(ch_ptr1);for(size_t i=0; i<nLen; i++){	*ch_ptr_A++ = *ch_ptr1++; // this is the culprit line, i think!}
(Well, actually you should be using std::string [smile])

EDIT: D'oh! 1 minute too late [smile]
ToohrVyk
ToohrVyk
There are several other problems with your code.
  1. You have a buffer overflow in your code: you must never write std::cin >> arr; when arr is an array of characters or a pointer to a character buffer, because it allows the data to overflow the array or buffer. Always use std::cin.getline with an appropriate character count and delimiter instead.

  2. You are quite possibly mistaken in your usage of std::cin >> arr anyway, since it will only read up to the first whitespace character. That is, if the user inputs "Hello world" and the buffer is at least six characters wide, then it will contain "Hello". You can only read the entire string by using getline, which reads whitespace characters unless you ask it not to.

  3. If you insist on doing things the C way, you already have access to C standard library functions that copy strings for you, namely strncpy. Of course, safe buffer manipulation in C requires that you pass the length of your buffers as an argument to your functions, so your code would look like:
    #include <cstring>void FillDisks(const char *src, const char*, char *dest, int n){  strncpy(dest, n, src);}


  4. Of course, C++ has a string class which already handles these silly operations, making your code look like:
    #include <string>std::stringFillDisks(const std::string & src,          const std::string &){  return src;}
styfir
styfir
Thanks guys that worked! I used the first guys' reply! I didn't know of 'size_t' as I'm still new to c and c++

Appreciate the other answers as well - cheers!!

can somebody shine some light on 'size_t'? Is it a type?
stonemetal
stonemetal
As with most types in C it is a define for some other type. In C there are 5 types: int, void, float, double, char. C++ adds two types bool and wchar_t. From there they add type modifiers such as signed, unsigned, short, long. If you type a modifier without a type such as long instead of long int the base is assumed to be int. size_t is more than likely defined to be unsigned int or unsigned long int.
ToohrVyk
ToohrVyk
Quote:
Original post by stonemetal
In C there are 5 types: int, void, float, double, char.


The five C base types are int, float, double, char and void*. void is not a type, it's a keyword indicating the absence of a type.
Evil Steve
Evil Steve
Quote:
Original post by styfir
Thanks guys that worked! I used the first guys' reply! I didn't know of 'size_t' as I'm still new to c and c++

Appreciate the other answers as well - cheers!!

can somebody shine some light on 'size_t'? Is it a type?
If you're using Microsoft Visual Studio, if you turn your warning level up to level 4 (maximum) and enable 64-bit portability warnings, you'll get errors about truncation from size_t to int in your code (Since on a x64 build, size_t is 8 bytes and int is 4).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.