2

I have a char[4] dataLabel that when I say

wav.read(dataLabel, sizeof(dataLabel));//Read data label cout << "Data label:" <<dataLabel << "\n"; 

I get the output Data label:data� but when I loop through each char I get the correct output, which should be "data".

for (int i = 0; i < sizeof(dataLabel); ++i) { cout << "Data label " << i << " " << dataLabel[i] << "\n"; } 

The sizeof returns 4. I'm at a loss for what the issue is.

EDIT: What confuses me more is that essentially the same code from earlier in my program works perfectly.

ifstream wav; wav.open("../../Desktop/hello.wav", ios::binary); char riff[4]; //Char to hold RIFF header if (wav.is_open()) { wav.read(riff, sizeof(riff));//Read RIFF header if ((strcmp(riff, "RIFF"))!=0) { fprintf(stderr, "Not a wav file"); exit(1); } else { cout << "RIFF:" << riff << "\n"; 

This prints RIFF:RIFF as intended.

5
  • 6
    Is your char array null terminated? If it is not it could explain the issue. Try making it 5 characters and making the last character '\0' Commented Jul 7, 2015 at 20:33
  • 2
    @marsh - you're very correct, just not confident enough. Matt noted the array is of size 4 (char[4] dataLabel), and the data it holds is 4 characters long ("data"). It is definitely missing the null character. Commented Jul 7, 2015 at 20:36
  • try char[5] dataLabel. If "data" is being read in, there's no space for the \0 character! Commented Jul 7, 2015 at 20:36
  • @Amit ah yes good catch. I did not notice the string was listed. Commented Jul 7, 2015 at 20:44
  • The code seemed to work fine using essentially the same lines earlier. I'm curious why that would be, see the edit Commented Jul 8, 2015 at 13:11

5 Answers 5

3

You are missing a null terminator on your character array. Try making it 5 characters and making the last character '\0'. This lets the program know that your string is done without needing to know the size.

What is a null-terminated string?

Sign up to request clarification or add additional context in comments.

5 Comments

What happens if there is no null terminator? It seemed like it worked fine previously in my code.
It will work as long as you are aware of the length and are iterating through it. Though it is definitely not recommended. As you can see many built in functions dealing with char arrays use the null terminate to find out when it ends. It may lead to trouble down the road. A std::string may be a smart choice as well, though without seeing all your code it is hard to say. If it worked before with cout, chances are that where your string was placed in memory happened to be surrounded by nulled out data. This is random and cannot be assured to stay the same.
See my edit. Why does it work there but not in the original question? Thanks
So it's undefined behavior that changes each time? Thanks. I'm going to change it to std::string
Basically yes, it just depends where the string is put in memory, that is my theory anyway. A more experienced member may come up with a better reason. std::string is optimized for small values anyway so it should not be a performance hit.
1

The overload of operator<< for std::ostream for char const* expects a null terminated string. You are giving it an array of 4 characters.

Use the standard library string class instead:

std::string dataLabel; 

Comments

0

See the documentation for istream::read; it doesn't append a null terminator, and you're telling it to read exactly 4 characters. As others have indicated, the << operator is looking for a null terminator so it's continuing to read past the end of the array until it finds one.

I concur with the other suggested answer of using std::string instead of char[].

Comments

0

Your char[] array is not null-terminated, but the << operator that accepts char* input requires a null terminator.

char dataLabel[5]; wav.read(dataLabel, 4); //Read data label dataLabel[4] = 0; cout << "Data label:" << dataLabel << "\n"; 

Comments

0

Variable dataLabel is defined like

char[4] dataLabel; 

that it has only four characters that were filled with characters { 'd', 'a', 't', 'a' ) in statement

wav.read(dataLabel, sizeof(dataLabel));// 

So this character array does not have the terminating zero that is required for the operator << when its argument is a character array.

Thus in this statement

cout << "Data label:" <<dataLabel << "\n"; 

the program has undefined behaviour.

Change it to

std::cout << "Data label: "; std::cout.write( dataLabel, sizeof( dataLabel ) ) << "\n"; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.