使用C在csv中的逗号之间放置零

Posted

技术标签:

【中文标题】使用C在csv中的逗号之间放置零【英文标题】:Putting zero between commas in csv using C 【发布时间】: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 可能有问题。 "while( !feof( file ) )" is always wrong 的可能重复项 1,2,,,,3, 将输出1,2,0,0,0,3,0,0 【参考方案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;

逻辑

    源字符串和目标字符串需要不同的索引,因为目标字符串的索引在插入'0' 时必须增加两次。 如果当前字符不是',',我们可以将其添加到目标字符串中。 如果当前字符是',',但前一个字符不是',',我们可以将','复制到目标字符串。 如果当前字符是',',前一个字符是',',我们必须在目标字符串中插入'0'。我们还需要包含“,'”。在此块中,目标索引必须增加两次。 如果目标字符串中插入的最后一个字符是',',请在其中添加另一个'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 语句以在我的预期迭代中结束循环。现在它按预期工作。

以上是关于使用C在csv中的逗号之间放置零的主要内容,如果未能解决你的问题,请参考以下文章

使用 SSMS 在 where 子句中的每个 id 之前放置逗号

Clojure CSV 解析引号中的逗号

使用交叉连接和在两个表之间放置逗号有啥区别?

csv中的Python嵌套逗号

读取缺少逗号的 .csv 文件。碱基R

如果存在,则删除双引号之间的第一个逗号