用sscanf

时间:2016-04-26 05:09:15

标签: c string file space scanf

我正在尝试使用sscanf读取字符串,以便在拆分时将此扫描的字符串用作文件的名称。

问题是sscanf只读取文件中存在的第一个空格,通常会发生什么。但是,我在Stack Overflow中看到了很多关于如何读取这些空间的提示。

不幸的是,所有这些似乎都是一样的,只需在函数中添加%[^\t\n\0]或类似的东西。

问题是这种方法对我不起作用,我无法确定原因;我尝试了我在这里找到的所有技巧,但没有一个能够正常工作。

如果有人可以帮我识别问题,我将不胜感激。

以下是代码:

int TAM_BUFFER = 75; 
int filecounter=1, linecounter=1;

int main(int argc, char *argv[]){

    char fileoutputname[15];
    char buffer[TAM_BUFFER];
    char buffer2[15];
    char buffer3[15];

    FILE *arquivo = fopen("Entrada.txt", "r");
    FILE *saida;

    sprintf(fileoutputname, "%s.txt", buffer2);
    saida = fopen(fileoutputname, "w");

    if(arquivo != NULL){

        while(fgets(buffer, TAM_BUFFER, arquivo)){
            if(linecounter==2){
                strncpy(buffer2,buffer,sizeof buffer2 - 1);
                buffer2[sizeof buffer2 - 1] = '\0';
            }

            if (strncmp(buffer,"NEWDAY",strlen("NEWDAY")) == 0){
                fclose(saida);
                linecounter = 1;
                filecounter++;
                sscanf(buffer2, "%s", &buffer3);
                printf("strlen(%s)=%d\n", buffer3, (int) strlen(buffer3));
                sprintf(fileoutputname, "%s.txt", buffer3);
                saida = fopen(fileoutputname, "w");
                if (!saida)
                    return 1;       
            }

            fprintf(saida,"%s\n", buffer);
            linecounter++;

        }
    }

    fclose(arquivo);
    fclose(saida);
    return 0;
}

*我想做的是获取文件的第二行,并使用前14个字符作为文件的名称。

文件的输入是这一个:

TAM 2000-03-07T14:00    22.78   5.50999 2   786 2.8 798 2.8 186 0.0 298 3.2
TAM 2000-03-08T14:01    22.78   5.50999 2   779 1.2 793 1.0 186 0.0 300 1.5
TAM 2000-03-07T14:02    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:03    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:04    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-17T14:05    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:06    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
NEWDAY
TAM 2000-03-08T14:09    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:10    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:11    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-09T14:12    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
NEWDAY
TAM 2000-03-09T14:13    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-31T14:14    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:15    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:16    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:17    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:18    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-02T14:19    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

3 个答案:

答案 0 :(得分:1)

如果您决定放弃sscanf(),则可以使用fgets()代替..

#include <stdio.h>

int main()
{
    char buffer2[200] = "Name with Spaces";

    FILE *fp;
    fp = fmemopen (buffer2, strlen (buffer2), "r"); 

    char str[200];
    if ( fgets(str, 200, fp) != NULL ) 
    {
        printf("Scanned Name: %s \n", str );
    }
}

答案 1 :(得分:1)

基本上,如:

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

答案 2 :(得分:1)

如评论中所述,您有许多字符串,这些字符串对于您声明的数组来说太长了。具体来说,您的数据文件行长75个字符,不适合75字符缓冲区。进行更改并稍微调整变量名称,您可以执行以下操作:

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

enum { BUFL = 20, TAMB = 80 };

int main (int argc, char **argv) {

    int fcnt = 1, lcnt = 1;
    char buf[TAMB] = "", buf2[BUFL] = "", buf3[BUFL] = "";
    char ofn[BUFL] = "";
    FILE *ifp = argc > 1 ? fopen (argv[1], "r") : stdin;
    FILE *ofp = argc > 2 ? fopen (argv[2], "w") : stdout;
    if (!ifp || !ofp) {
        fprintf (stderr, "error: file open failed.\n");
        return 1;
    }

    while (fgets (buf, TAMB, ifp)) {
        char *p = buf;
        for (; *p && *p !='\n'; p++) {} /* remove trailing \n */
        if (*p) *p = 0; /* overwrite '\n' with nul-terminator */

        if (lcnt == 2) {
            strncpy (buf2, buf, BUFL - 1);
            buf2[BUFL - 1] = 0;
        }

        if (strncmp (buf, "NEWDAY", strlen("NEWDAY")) == 0) {
            fclose (ofp);
            lcnt = 1;
            fcnt++;
            // sscanf (buf2, "%s", &buf3);
            strcpy (buf3, buf2);
            printf ("strlen (%s) = %zu\n", buf3, strlen (buf3));
            sprintf (ofn, "%s.txt", buf3);
            ofp = fopen (ofn, "w");
            if (!ofp)
                return 1;       
        }
        fprintf (ofp, "%s\n", buf);
        lcnt++;
    }

    if (ifp != stdin) fclose (ifp);

    return 0;
}

示例输入文件

$ cat dat/newday.txt
TAM 2000-03-07T14:00    22.78   5.50999 2   786 2.8 798 2.8 186 0.0 298 3.2
TAM 2000-03-08T14:01    22.78   5.50999 2   779 1.2 793 1.0 186 0.0 300 1.5
TAM 2000-03-07T14:02    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:03    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:04    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-17T14:05    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:06    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
NEWDAY
TAM 2000-03-08T14:09    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:10    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-07T14:11    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-09T14:12    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
NEWDAY
TAM 2000-03-09T14:13    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-31T14:14    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:15    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:16    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:17    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:18    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-02T14:19    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

示例使用/输出文件

$ ./bin/readspaces dat/newday.txt dat/newdayout.txt
strlen (TAM 2000-03-08T14:0) = 19
strlen (TAM 2000-03-08T14:0) = 19

$ cat dat/newdayout.txt
TAM 2000-03-07T14:00    22.78   5.50999 2   786 2.8 798 2.8 186 0.0 298 3.2

TAM 2000-03-08T14:01    22.78   5.50999 2   779 1.2 793 1.0 186 0.0 300 1.5

TAM 2000-03-07T14:02    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-07T14:03    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-07T14:04    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-17T14:05    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-07T14:06    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9


$ cat TAM\ 2000-03-08T14\:0.txt
NEWDAY

TAM 2000-03-09T14:13    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-31T14:14    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-01T14:15    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-01T14:16    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-01T14:17    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-01T14:18    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

TAM 2000-03-02T14:19    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

注意:存在其他行,因为您无法修改'\n'读取并buf fgets中包含{/ 1}}

修复换行问题后,输出文件为:

$ cat TAM\ 2000-03-08T14\:0.txt
NEWDAY
TAM 2000-03-09T14:13    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-31T14:14    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:15    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:16    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:17    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:18    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-02T14:19    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

查看更改,如果您有任何疑问,请与我们联系。目前还不清楚你试图用缓冲区2/3大小实现的长度,但是你可以调整BUFL常数以使其符合你的需要。另请注意,您只需将buffer2复制到buffer3,就不需要snprintf语句。

看起来15 spacing会产生代码的outputfilename部分所需的结果。将BUFL更改为15可提供:

$ ./bin/readspaces dat/newday.txt dat/newdayout.txt
strlen (TAM 2000-03-08) = 14
strlen (TAM 2000-03-08) = 14

然后生成输出文件:

$ cat TAM\ 2000-03-08.txt
xt
TAM 2000-03-09T14:13    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-31T14:14    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:15    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:16    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:17    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-01T14:18    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9
TAM 2000-03-02T14:19    22.78   5.50999 2   773 3.0 788 3.8 186 0.1 300 0.9

注意:但是,输出文件开头的NEWDAY的一些未定义行为不是xt