【问题标题】:Putting zero between commas in csv using C使用C在csv中的逗号之间放置零
【发布时间】:2013-12-24 05:44:35
【问题描述】:

我这里有这段代码:

#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;
}

此代码的作用是在 csv 中的连续逗号之间添加零,例如,1,2,,,,3, -> 1,2,0,0,0,3,0

我的代码适用于以逗号结尾的 csv,如上面的示例,但不适用于以值结尾的 csv,如 1,2,3,4,5(我得到的是 1,2,3,4,55,而是末尾有额外的“5”)。

任何人都可以提出代码中的问题吗?谢谢。

【问题讨论】:

  • 首先,读取单个char 使用char buffer; 而不是数组。并尝试使用buffer = fgetc(inFile); 而不是fscanf,我只是猜测fscanf 可能有问题。
  • 1,2,,,,3, 将输出1,2,0,0,0,3,0,0

标签: c csv comma


【解决方案1】:

代码

#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;
}

逻辑

  1. 源字符串和目标字符串需要不同的索引,因为目标字符串的索引在插入'0' 时必须增加两次。
  2. 如果当前字符不是',',我们可以将其添加到目标字符串中。
  3. 如果当前字符是',',但前一个字符不是',',我们可以将','复制到目标字符串。
  4. 如果当前字符是',',前一个字符是',',我们必须在目标字符串中插入'0'。我们还需要包含“,'”。在此块中,目标索引必须增加两次。
  5. 如果目标字符串中插入的最后一个字符是',',请在其中添加另一个'0'

输出

1,2,,,3,4,,,
1,2,0,0,3,4,0,0,0
按任意键继续 。 . .

重构你的代码

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;
}

【讨论】:

  • +1 用于给出逻辑。但是如果你通过文件 I/O 来做到这一点会更好。
  • @hacks 谢谢。我不希望任何人只是复制和粘贴。重要的是逻辑。
  • 谢谢。我理解你的逻辑,我已经修改了我的代码。它现在按预期工作。
【解决方案2】:

最后一位数字(即“1,2,3,4,55”)重复的原因是因为 while 循环 (while(!feof(inFile))) 比实际可用数据多运行一次迭代文件。

fscanf(inFile,"%c",&buffer);的返回值可以检查以确保从文件中读取的值是有效的。否则设置为 EOF (0xFFFFFFFF)

【讨论】:

  • 谢谢。我重新分析了我的代码并添加了一个 break 语句以在我的预期迭代中结束循环。现在它按预期工作。
猜你喜欢
  • 2022-07-04
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2015-08-12
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多