Weird behavior of "cout" when i used strncpy before

Hi there, thanks for reading my post.

I try to make a simple programm, which is reading lines from a txt file, my goal is to flip the string if the user wants this, something like: "Hans Peter" should result in: "Peter Hans".

Reading from a txt file is working, same with cut the string and put together again, but then i tried (just for debuging) to cout<<theNewName, it does not take the whole charArray[] on one line... after the first part a new line begins... and i dont know why, so i tried another way and it did work properly, here are the code with both functions drehen1() does the right thing but in drehen2() the output is wrong. Only diffrence is that i used strncpy()... has anyone a clue why drehen2() doesnt work like expected?

(Sorry for my bad English)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <cstdlib>
#include <string.h>
#include <cstdio>

using namespace std;

void drehen(char*);
void drehen2(char*);

int main()
{
	char eingabe[20];
	char drehe;
	cout<<"Vertauschen"<<endl;
	cout<<"==========="<<endl;
	cout<<"Bitte Filenamen eingeben: ";
	cin>>eingabe;
	fflush(stdin);
	FILE *fp=fopen("dienamen.txt", "r");
	if(fp==NULL)
	{
		cout<<"File existiert nicht!";
		return 1;
	}
	char zeichen[50];

	while(!feof(fp))
	{
		//Zeile Einlesen
		fgets(zeichen, 50, fp);
		cout<<zeichen;
		cout<<"Drehen?\t\t <J/N>: ";
		cin>>drehe;
		fflush(stdin);
		//Drehen oder nicht
		if(drehe == 'j' || drehe == 'J')
		{
			//drehen(zeichen);
			drehen2(zeichen);
		}
	}
}


void drehen(char * zeile)
{
	char vorname[30]="\0";
	char nachname[30]="\0";
	int i=0, j=0;
	while(zeile[i]!= ' ')
	{
		nachname[i]=zeile[i];
		i++;
	}
	i++;
	while(isalnum(zeile[i]) || zeile[i]=='-')
	{
		vorname[j]=zeile[i];
		j++;
		i++;
	}
	strcpy(zeile, vorname);
	strcat(zeile, " ");
	strcat(zeile, nachname);
	strcat(zeile, "\n");
	cout<<"Funktion drehen1"<<endl;
	cout<<zeile<<endl;
}


void drehen2 (char * zeile)
{
	char vorname[30]="\0";
	char nachname[30]="\0";
	for(int a = 0; a<strlen(zeile); a++)
	{
		char b;
		b=zeile[a];
		if(b== ' ')
		{
			strncpy(vorname, zeile, a);
			strcat(vorname, "\0");
			int c = 0;
			a++;
			while(a <= strlen(zeile))
			{
				nachname[c]=zeile[a];
				a++;
				c++;
			}
			strcpy(zeile, nachname);
			strcat(zeile, " ");
			strcat(zeile, vorname);
			strcat(zeile, "\n");
			cout<<"Funktion drehen2"<<endl;
			cout<<zeile<<endl;
		}
	}

}


(It isnt finish yet i need to write back the name after changing it but it should run)

Thank you all for your help
You should really decide if you want to write a C or C++ program. If you want to write a C++ program I suggest you use C++ streams instead of C stdio functions.

You have several problems with your code. First fflush() is not defined in the standard to work with input streams. Second don't forget that fgets() leaves the new line character in the C-string. Lastly I don't really understand why you keep putting the new line character into your C-string. Normally one would remove that character not insert it.

Hi jlb thanks for your answer, first of all we are learning C in school but we use cout and cin for input output, i dont know why thats why im using it, and teacher told us that we should use the libraries with a c at the begining, and i never asked why... :) i think c libraries are the one like cmath? and C++ is math.h?

Ah ok so i dont need the fflush() did not know that, i thougt that the fflush() would delete the ENTER which is somewhere because its not in the string where i save the input. But thanks for the information now i know better.

I do add the "\n" because i want to write back the name in a txt file.

I changed some of the things u mentioned but still no effect.
Example: Hans Peter

drehen1() = Peter Hans (does work)
drehen2() = Peter\nHans (i dont see the "\n" in the string its just to show that the output is in 2 lines)
Change this
82
83
        strncpy(vorname, zeile, a);
        strcat(vorname, "\0");

to this:
82
83
        strncpy(vorname, zeile, a);
        vorname[a] = '\0';

The reason why you add the null-terminator is to mark the end of the string. strcat does not work, as it does not yet know where the end of the string actually is.

Also, this line is dangerous: strcat(zeile, "\n"); because it makes the new string longer than the original string, which may corrupt some other adjacent memory with unpredictable results.
Last edited on
Thanks Chervil for your answer.

I added the changes but still no effect. Output is the same.

Is it allowed to link to a picture where u can see the 2 diffrent outputs?
Last edited on
Please post your current code and a small sample of your input file.

Normally you don't want your strings to have the end of line character embedded within them. You normally take care of adding the end of line character when you print the string to your file.

i think c libraries are the one like cmath? and C++ is math.h?

No in C programs the C include file are like <math.h> and in C++ programs the standard C include files are like <cmath>. Also note include files are not the same things as libraries.

Last edited on
OK here we go this is the whole code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std;

void drehen(char*);
void drehen2(char*);

int main()
{
	char eingabe[20];
	char drehe;
	cout<<"Vertauschen"<<endl;
	cout<<"==========="<<endl;
	cout<<"Bitte Filenamen eingeben: ";
	cin>>eingabe;
	FILE *fp=fopen("dienamen.txt", "r");
	if(fp==NULL)
	{
		cout<<"File existiert nicht!";
		return 1;
	}
	char zeichen[50];

	while(!feof(fp))
	{
		//Zeile Einlesen
		fgets(zeichen, 50, fp);
		cout<<zeichen;
		cout<<"Drehen?\t\t <J/N>: ";
		cin>>drehe;
		//Drehen oder nicht
		if(drehe == 'j' || drehe == 'J')
		{
			//drehen(zeichen);
			drehen2(zeichen);
//Here will be something like newFilePointer=fopen("newFile.txt", "w");
//fputs(zeichen);
		}
	}
}


void drehen(char * zeile)
{
	char vorname[30]="\0";
	char nachname[30]="\0";
	int i=0, j=0;
	while(zeile[i]!= ' ')
	{
		nachname[i]=zeile[i];
		i++;
	}
	i++;
	while(isalnum(zeile[i]) || zeile[i]=='-')
	{
		vorname[j]=zeile[i];
		j++;
		i++;
	}
	strcpy(zeile, vorname);
	strcat(zeile, " ");
	strcat(zeile, nachname);
	strcat(zeile, "\n");
	cout<<"Funktion drehen1"<<endl;
	cout<<zeile<<endl;
}


void drehen2 (char * zeile)
{
	char vorname[30]="\0";
	char nachname[30]="\0";
	for(int a = 0; a<strlen(zeile); a++)
	{
		char b;
		b=zeile[a];
		if(b== ' ')
		{
			strncpy(vorname, zeile, a);
			vorname[a]='\0';
			int c = 0;
			a++;
			while(a <= strlen(zeile))
			{
				nachname[c]=zeile[a];
				a++;
				c++;
			}
			strcpy(zeile, nachname);
			strcat(zeile, " ");
			strcat(zeile, vorname);
			//strcat(zeile, "\n");
			cout<<"Funktion drehen2"<<endl;
			cout<<zeile<<endl;
		}
	}

}


TextFile:
Hans Peter
Marco Test
Mister Right
Name Vorname

It is a simple txt file, on each line is a new name. This is everything i got :) Hope that helps.

Greezzz APSy
Last edited on
What I recommend is that you remove the end of line character from your string, if it exists right after your fgets(). And the don't place this character in your string in your function.

1
2
3
4
5
		fgets(zeichen, 50, fp);
		if(zeichen[strlen(zeichen)-1] == '\n')
         zeichen[strlen(zeichen)-1] = '\0';

		cout << zeichen << endl;


Note the addition of the "endl" when you print the string.

And the function.
1
2
3
4
	strcpy(zeile, vorname);
	strcat(zeile, " ");
	strcat(zeile, nachname);
	//strcat(zeile, "\n"); // This is not needed or wanted. 


Ahhhh now it works... and now i understand why there was a newline in between, i used "==" in my example instead of "=", before i got here..

But with your code it does run perfectly thank u so much for your help, it was allways the newline i couldnt get rid of.

1
2
3
fgets(zeichen, 50, fp);
if(zeichen[strlen(zeichen)-1] == '\n')
zeichen[strlen(zeichen)-1] = '\0';


The new Code: (working now)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std;

void drehen(char*);
void drehen2(char*);

int main()
{
	char eingabe[20];
	char drehe;
	cout<<"Vertauschen"<<endl;
	cout<<"==========="<<endl;
	cout<<"Bitte Filenamen eingeben: ";
	cin>>eingabe;
	FILE *fp=fopen("dienamen.txt", "r");
	if(fp==NULL)
	{
		cout<<"File existiert nicht!";
		return 1;
	}
	char zeichen[50]="\0";

	while(!feof(fp))
	{
		//Zeile Einlesen
		fgets(zeichen, 50, fp);
		if(zeichen[strlen(zeichen)-1] == '\n')
			zeichen[strlen(zeichen)-1] = '\0';
		cout<<zeichen;
		cout<<"Drehen?\t\t <J/N>: ";
		cin>>drehe;
		//Drehen oder nicht
		if(drehe == 'j' || drehe == 'J')
		{
			//drehen(zeichen);
			drehen2(zeichen);
			cout<<zeichen;
		}
	}
}


void drehen(char * zeile)
{
	char vorname[30]="\0";
	char nachname[30]="\0";
	int i=0, j=0;
	while(zeile[i]!= ' ')
	{
		nachname[i]=zeile[i];
		i++;
	}
	i++;
	while(isalnum(zeile[i]) || zeile[i]=='-')
	{
		vorname[j]=zeile[i];
		j++;
		i++;
	}
	strcpy(zeile, vorname);
	strcat(zeile, " ");
	strcat(zeile, nachname);
	strcat(zeile, "\n");
	cout<<"Funktion drehen1"<<endl;
	//cout<<zeile<<endl;
}


void drehen2 (char * zeile)
{
	char vorname[30]="\0";
	char nachname[30]="\0";
	for(int a = 0; a<strlen(zeile); a++)
	{
		char b;
		b=zeile[a];
		if(b== ' ')
		{
			strncpy(vorname, zeile, a);
			vorname[a]='\0';
			int c = 0;
			a++;
			while(a <= strlen(zeile))
			{
				nachname[c]=zeile[a];
				a++;
				c++;
			}
			strcpy(zeile, nachname);
			strcat(zeile, " ");
			strcat(zeile, vorname);
			cout<<"Funktion drehen2"<<endl;
			//cout<<zeile;
		}
	}

}


Thanks everyone for your help i really appreciate it, special thanks to jlb who solved it. Have a nice day and see you soon maybe ;)
Last edited on
The reason why the first version worked was the use of isalnum() which ignored the newline.
Topic archived. No new replies allowed.