• C

Leftover data in strings

I am writing a C program that is taking input from a file.   Somehow it seems that data is being leftover in certain strings, even after performing a strcpy(string, "");

I may have other questions depending on whether this one gets resolved or not, and if so I will increase the points if anyone cares to answer them.  

What heppens is that both of the strings returned by getLabel and getMnemonic are fine, but the operand string stored by getOperand contains data left over from the previous call.  This code is inside of a while(!feof(inputFile).  When if goes through the first time, say that Length is stored in the operand field.  If the second time, RD is supposed to be stored, it will store it as RDngth with the ngth left over from the last iteration.  Also, if you print out the inputLine received by the function it does NOT contain the ngth, it would end in RD instead.  I have tried many different things including for loops assigning null characters and other print jobs, but nothing seems to work.  Here is the main part of the code that's failing in this way.

j = 0;
        strcpy(inputLine, "");
        while ((j < 70) && ((tempChar = fgetc(inputFile)) != '\n') && !feof(inputFile)) {
          inputLine[j] = tempChar;
        }//end while
        inputLine[j] = '\0';
        if (lineNumber < 10) {
          fprintf(interFile, "%d    %s\n", lineNumber, inputLine);
        } else {
          fprintf(interFile, "%d   %s\n", lineNumber, inputLine);
        }//end if/else
        strcpy(label, "");
        strcpy(mnemonic, "");
        strcpy(operand, "");
        gotLabel = getLabel(label, inputLine);
        gotMnemonic = getMnemonic(mnemonic, inputLine);
        gotOperand = getOperand(operand, inputLine);

Here is the getOperand function:
the j is present because the 19th column of the line is where the contents are inside of the file.

int getOperand(char* operand, char *input) {

  int i = 0;
  int j = 18;
  //printf("%s\n", input);
  for (i=0; i < 25; i++){
    if(isalnum(input[i+j])) {
      operand[i] = input[i+j];
    } else if(isspace(input[i+j])) {
      operand[i] = '\0';
      return 1;
    } else {
      if (input[i+j] == ',' || ((input[i+j] == '@' || input[i+j] == '#') && i == 0)) {
        operand[i] = input[i+j];
      } else {
      }//end else
    }//end if
  }//end for
}//end function getOperand

Any help would be greatly appreciated.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

To avoid this problem, the function should store a null character at the end of the operand string no matter what.  As it is, it only does that if there is whitespace after the operand.  It may be encountering one of the other cases where i gets to 25 or it returns SPECIAL_CHAR_IN_OPERAND.  In those cases, it returns without terminating the string.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
neverrealmAuthor Commented:
That worked well except that now if the "operand" field is blank in the text file it retains the value of the previous entry.  For instance if 1 iteration had length, and the next iteration has nothing, then length will also be contained in the second iteration
you need to check for the end of the input string.

      for (i=0; i < 25; i++){
      for (i=0; i < 25 && input[i+j]; i++){

-- Adil
ON-DEMAND: 10 Easy Ways to Lose a Password

Learn about the methods that hackers use to lift real, working credentials from even the most security-savvy employees in this on-demand webinar. We cover the importance of multi-factor authentication and how these solutions can better protect your business!

in fact, a better option would be to change

      } else if(isspace(input[i+j])) {

      } else if(isspace(input[i+j]) || input[i+j] == 0) {

keep the for-loop condition as it is:

      for (i=0; i < 25; i++){

-- Adil
neverrealmAuthor Commented:
That did not fix the problem.  Thank you though.
did you try the second way?

-- Adil
neverrealmAuthor Commented:
I actually hadn't when I wrote that, but then I did and it didn't work, so I didn't make an adjustment
The code that reads in a line guarantees that it will be null-terminated, but not that it will be 19 characters long.  If the terminating null character is before input[18], the getOperand function will be looking at data left over from a previous line.  So it would be a good idea for that function to make sure the input doesn't end before position 18 before it starts processing data at that location.
This certainly seems like a whole lot of work when using fgets(), strchr() or strtok()
would seem to  be much more appropriate.

Using fflush() makes your program highly intolerant of I/O redirection.

strcpy(string, "")  is a very inefficient way to empty a string.  You will commonly
see  string[0] = '\0'; instead.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.