简体   繁体   English

CSV(ish)文本处理 - Windows 上的 output 不正确,适用于 Linux

[英]CSV(ish) text handling - incorrect output on Windows, works on Linux

I am learning C and I don't understand why this code doesn't work.我正在学习 C,但我不明白为什么这段代码不起作用。

It's supposed to skip the first character, separate it in 8,4,4,4,4.它应该跳过第一个字符,将其分隔为 8,4,4,4,4。 But it adds one extra "0" to beginning of the second column and shifts the rest.但它会在第二列的开头添加一个额外的“0”并移动 rest。

Also when I try to run it on Windows I can't see any results.此外,当我尝试在 Windows 上运行它时,我看不到任何结果。 Sometimes it can't open the file, sometimes the output is wrong.有时候打不开文件,有时候output是错的。

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

const int MAX_LINES = 10000000;

char s[1000];
int lines;
FILE *fptrIn, *fptrOut;

void convertData(char *s) {
    s[28] = 0;

    char gp1[8 + 1] = {0};
    char gp2[4 + 1] = {0};
    char gp3[4 + 1] = {0};
    char gp4[4 + 1] = {0};
    char gp5[4 + 1] = {0};
    char gp6[4 + 1] = {0};

    strncpy(gp1, s + 1, 8);
    strncpy(gp2, s + 8, 4);
    strncpy(gp3, s + 12, 4);
    strncpy(gp4, s + 16, 4);
    strncpy(gp5, s + 20, 4);
    strncpy(gp6, s + 24, 4);

    fprintf(fptrOut, "%s;%s;%s;%s;%s;%s\n", gp1, gp2, gp3, gp4, gp5, gp6);
}

int main() {

    if ((fptrIn = fopen("test.txt", "r")) == NULL) {
        printf("Error opening file!");
        return 1;
    }

    fptrOut = fopen("testout1.txt", "w");

    fprintf(fptrOut, "Position;Sens1;Sens2;Sens3;Check;Time\n");

    while(fgets(s, sizeof s, fptrIn) != NULL) {
        lines++;
        if (strlen(s) < 28)
            continue;
        printf("Line %d#:\n", lines);
        printf("%s\n", s);
        convertData(s);
        if (lines == MAX_LINES) {
            break;
        }
    }

    fclose(fptrIn);
    fclose(fptrOut);

    return 0;
}

Input data:输入数据:

U66ACA1000D8007670000035CBE5Cd;
U66C668000D0A07DA0000037CBF60;
U66DF84000C9908480000038CC05A(;
U66F8A0000C2A08B6000003A9C154Ä;
U67114A800BBB0923000003C9C24E„;
U6729F5000B490991000003D9C348];

The output using Linux: output 使用 Linux:

Position; Sens1; Sens2; Sens3; Check; Time;
66ACA100; 00D8; 0076; 7000; 0035; CBE5;
66C66800;00D0;A07D;A000;0037;CBF6;
66DF8400;00C9;9084;8000;0038;CC05;
66F8A000;00C2;A08B;6000;003A;9C15;
67114A80;00BB;B092;3000;003C;9C24;
6729F500;00B4;9099;1000;003D;9C34;

And here is the whole output on Windows (although WSL is running):这是 Windows 上的整个 output(尽管WSL正在运行):

Position;Sens1;Sens2;Sens3;Check;Time;

66ACA100;0D80;0767;0000;035C;BE5
00F3B054;8000;0039;9DDE;2‘
U;69F
27000003;A6FD;687
;U6D1;D3B8;000
3731CEEÕ;
U70;4A17;0002;3901;7A0

U73764;8000;3F20;F570;0000;340

There isn't any need to transfer the different fields out of s[ ] ...没有任何必要将不同的字段从s[ ] ...

printf() will do what you want... printf()会做你想做的...

printf( "%8.8s,%4.4s,%4.4s,%4.4s,%4.4s,%4.4s\n",
    s + 1,
    s + 1+8,
    s + 1+8+4,
    s + 1+8+4+4,
    s + 1+8+4+4+4,
    s + 1+8+4+4+4+4
    );

The compiler will 'do the math', collapsing those sums into single values in the object file.编译器将“进行数学运算”,将这些总和折叠成 object 文件中的单个值。 Having all the numbers laid out this way in the source code makes clear the different offsets.在源代码中以这种方式排列的所有数字清楚地表明了不同的偏移量。

One other thing... If the first character of each line is 'skipped' then you want characters in positions 1 to 28... s[28] = 0 is both wrong and unnecessary.另一件事...如果每行的第一个字符被“跳过”,那么您希望位置 1 到 28 中的字符... s[28] = 0既错误又不必要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM