[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 199
  • Last Modified:

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, "");
        fflush(inputFile);
        while ((j < 70) && ((tempChar = fgetc(inputFile)) != '\n') && !feof(inputFile)) {
          inputLine[j] = tempChar;
          j++;
        }//end while
        inputLine[j] = '\0';
        lineNumber++;
        if (lineNumber < 10) {
          fprintf(interFile, "%d    %s\n", lineNumber, inputLine);
        } else {
          fprintf(interFile, "%d   %s\n", lineNumber, inputLine);
        }//end if/else
        fflush(interFile);
        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);
  //fflush(stdout);
  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 {
        return SPECIAL_CHAR_IN_OPERAND;
      }//end else
    }//end if
  }//end for
}//end function getOperand

Any help would be greatly appreciated.
0
neverrealm
Asked:
neverrealm
  • 3
  • 3
  • 2
  • +1
2 Solutions
 
efnCommented:
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.
0
 
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
0
 
SadrulCommented:
you need to check for the end of the input string.

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

-- Adil
0
Easily manage email signatures in Office 365

Managing email signatures in Office 365 can be a challenging task if you don't have the right tool. CodeTwo Email Signatures for Office 365 will help you implement a unified email signature look, no matter what email client is used by users. Test it for free!

 
SadrulCommented:
in fact, a better option would be to change

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

to
      } 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
0
 
neverrealmAuthor Commented:
That did not fix the problem.  Thank you though.
0
 
SadrulCommented:
did you try the second way?

-- Adil
0
 
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
0
 
efnCommented:
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.
0
 
brettmjohnsonCommented:
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.


0

Featured Post

SMB Security Just Got a Layer Stronger

WatchGuard acquires Percipient Networks to extend protection to the DNS layer, further increasing the value of Total Security Suite.  Learn more about what this means for you and how you can improve your security with WatchGuard today!

  • 3
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now