1

I have this code here :

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

int main()
{
    FILE *inFile, *outFile;
    int i;
    char buffer[1];
    bool lastIsComma = false;

    inFile = fopen("csv.txt","r");
    outFile = fopen("output.txt","w");

    while(!feof(inFile))
    {
        fscanf(inFile,"%c",&buffer);
        i = atoi(buffer);

        if((i!=0) || (*buffer == '0'))
        {
            fprintf(outFile,"%d",i);
            lastIsComma = false;
        }
        else
        {
            if((lastIsComma) && (feof(inFile)))
            {
                fputc('0',outFile);
            }
            if((lastIsComma) && (!feof(inFile)))
            {
                fputc('0',outFile);
                fputc(',',outFile);
            }
            if((!lastIsComma) && (feof(inFile)))
            {
                fputc(',',outFile);
                fputc('0',outFile);
            }
            if((!lastIsComma) && (!feof(inFile)))
            {
                fputc(',',outFile);
            }
            lastIsComma = true;
        }
    }

fclose(inFile);
fclose(outFile);
return 0;
}

What this code does is to add zero between consecutive commas in a csv, for example, 1,2,,,,3, -> 1,2,0,0,0,3,0

My code works for csv ending with commas like the example above, but not for csv ending with values, like 1,2,3,4,5 ( I got 1,2,3,4,55 instead, with an extra '5' at the end).

Can anybody suggest what is wrong in the code?

dbc
  • 104,963
  • 20
  • 228
  • 340
Chi Hang
  • 11
  • 2
  • First of all, to read single `char` use `char buffer;` not an array. And try using `buffer = fgetc(inFile);` instead of `fscanf`, I am just guessing there may be problem with `fscanf`. – 0xF1 Dec 24 '13 at 05:53
  • 1
    possible duplicate of ["while( !feof( file ) )" is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – n. m. could be an AI Dec 24 '13 at 05:54
  • `1,2,,,,3,` will results in output `1,2,0,0,0,3,0,0` – haccks Dec 24 '13 at 06:11

2 Answers2

1

Code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    const char *srcStr = "1,2,,,3,4,,,";
    char destStr[100] = {'\0'}, prevCh = '\0';
    int destIdx = 0;

    for(int srcIdx = 0; srcIdx < strlen(srcStr); srcIdx++)
    {
        if(srcStr[srcIdx] != ',')
        {
            destStr[destIdx++] = srcStr[srcIdx];
        }
        else if(prevCh != ',')
        {
            destStr[destIdx++] = srcStr[srcIdx];
        }
        else
        {
            destStr[destIdx++] = '0';
            destStr[destIdx++] = srcStr[srcIdx];
        }

        prevCh = srcStr[srcIdx];
    }

    if(destStr[destIdx - 1] == ',')
        destStr[destIdx] = '0';

    printf("%s\n", srcStr);
    printf("%s\n", destStr);

    system("pause");
    return 0;
}

Logic

  1. The source string and the destination string need different indexes because the destination string's index must increment twice when it inserts a '0'.
  2. If the current character is not ',', we can add it to the destination string.
  3. If the current character is a ',' but the previous character was not an ',', we can copy the ',' to the destination string.
  4. If the current character is a ',' and the previous character is a ',', we must insert a '0' into the destination string. We also need to include the ','. The destination index must increment twice in this block.
  5. If the last character inserted in the destination string is a ',', add another '0' to it.

Output

1,2,,,3,4,,,
1,2,0,0,3,4,0,0,0
Press any key to continue . . .

Refactoring Your Code

while((ch = getc(inFile)) != EOF)
{
    if(ch != ',')
    {
        destStr[destIdx++] = ch;
    }
    else if(prevCh != ',')
    {
        destStr[destIdx++] = ch;
    }
    else
    {
        destStr[destIdx++] = '0';
        destStr[destIdx++] = ch;
    }

    prevCh = ch;
}
Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46
0

The reason for the duplication of last digit (i.e "1,2,3,4,55") is because the while loop (while(!feof(inFile))) runs one iteration more than the actual available data in file.

The return value of fscanf(inFile,"%c",&buffer); can be checked to make sure the value read from file is valid. Otherwise it is set to EOF (0xFFFFFFFF)

  • Thanks. I have reanalyse my code and added a break statement to end the loop at my intended iteration. Now it's working as expected. – Chi Hang Dec 24 '13 at 07:26