Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带sscanf的阅读空间_C_String_File_Space_Scanf - Fatal编程技术网

带sscanf的阅读空间

带sscanf的阅读空间,c,string,file,space,scanf,C,String,File,Space,Scanf,我正在尝试使用sscanf读取一个字符串,以便在拆分文件时使用此扫描字符串作为文件名 问题是sscanf只读取文件中的第一个空格,这是正常情况。然而,我在Stack Overflow中看到了许多关于如何使其读取这些空间的提示 不幸的是,它们似乎都是一样的,只需在函数中添加一个%[^\t\n\0]或类似的内容即可 问题是这种方法对我不起作用,我无法确定原因;我尝试了我在这里找到的所有技巧,但没有一个有效 如果有人能帮我找出问题所在,我将不胜感激 代码如下: int TAM_BUFFER = 75;

我正在尝试使用
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

如果你决定放弃
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 );
    }
}
#包括
int main()
{
char buffer2[200]=“带空格的名称”;
文件*fp;
fp=fmemopen(buffer2,strlen(buffer2),“r”);
char-str[200];
如果(fgets(str,200,fp)!=NULL)
{
printf(“扫描名称:%s\n”,str);
}
}
基本上,例如:

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

int TAM_BUFFER = 75; 

int main(int argc, char *argv[]){
    char fileoutputname[15] = {0};
    char buffer[TAM_BUFFER];

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

    if(arquivo == NULL){
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    fscanf(arquivo, "%14c", fileoutputname);//first split file name
    saida = fopen(fileoutputname, "w");
    rewind(arquivo);

    while(fgets(buffer, sizeof buffer, arquivo)){
        if(strncmp(buffer,"NEWDAY", 6) == 0){ // strlen("NEWDAY") is 6
            long file_pos = ftell(arquivo);//or use fgetpos for large file, save file position
            fscanf(arquivo, "%14c", fileoutputname);//next file name
            fseek(arquivo, file_pos, SEEK_SET);//or use fsetpos (pair with fgetpos), restore file position
            saida = freopen(fileoutputname, "w", saida);//fclose(saida);saida=fopen(fileoutputname, "w");
        }
        fprintf(saida,"%s", buffer);//No add newline
    }
    fclose(arquivo);
    fclose(saida);
    return 0;
}
#包括
#包括
#包括
int TAM_缓冲区=75;
int main(int argc,char*argv[]){
char fileoutputname[15]={0};
字符缓冲区[TAM_缓冲区];
文件*arquivo=fopen(“Entrada.txt”、“r”);
档案*赛达;
if(arquivo==NULL){
佩罗尔(“福彭”);
退出(退出失败);
}
fscanf(arquivo,“%14c”,fileoutputname);//第一个拆分文件名
saida=fopen(fileoutputname,“w”);
倒带(阿奎沃);
while(fgets(buffer,sizeof buffer,arquivo)){
如果(strncmp(buffer,“NEWDAY”,6)=0){//strlen(“NEWDAY”)是6
long file_pos=ftell(arquivo);//或对大文件使用fgetpos,保存文件位置
fscanf(arquivo,“%14c”,fileoutputname);//下一个文件名
fseek(arquivo,file_pos,SEEK_SET);//或使用fsetpos(与fgetpos配对),恢复文件位置
saida=freopen(fileoutputname,“w”,saida);//fclose(saida);saida=fopen(fileoutputname,“w”);
}
fprintf(saida,“%s”,缓冲区);//不添加换行符
}
fclose(arquivo);
fclose(赛达);
返回0;
}

如注释中所述,对于所声明的数组,您有许多字符串太长。具体来说,数据文件行的长度为
75
char,无法放入
75
char缓冲区。进行更改并稍微调整变量名称,您可以执行以下操作:

#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

解决换行问题后,输出文件为:

$ 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
查看更改,如果您有任何问题,请告诉我。目前还不清楚使用buffer2/3大小想要达到的长度,但您可以调整
BUFL
常量,使其符合您的需要。另外请注意,您可以简单地将
buffer2
复制到
buffer3
,不需要
snprintf
语句


似乎间隔的
15
为代码的
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

能否请您向我们展示您试图解析的输入。另外,除了获取第一个空格分隔的“word”之外,执行
sscanf(buffer2,“%s”和buffer3)
的真正目的是什么?如果这不是目的,那么
sscanf
调用只是执行strcpy(buffer3,buffer2)的一种糟糕方式。你好,Joachim,在我按照您的指示并在一些测试后决定使用sscanf之前,您曾试图帮我完成这项工作。现在我可以阅读说明,但只能读到第一个空格。输入是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-07,但它在TAM中停止,
buffer2
的内容应该已经包含您想要的字符串。您是否已尝试打印出
buffer2
?顺便说一句
sprintf(fileoutputname,“%s.txt”,buffer2)
buffer2
未初始化。然后在
sprintf中使用str(fileoutputname,“%s.txt”,str)?是的,请确保
fileoutputname
足够大,我想您应该可以开始了。您可能想从fgets缓冲区中删除
\n
。我已经用
缓冲区完成了这项工作,然后我只是将这个
缓冲区的前14个字符复制到
缓冲区2
,因为我不需要所有字符。在此之后,我说
Buffer2
的最后一个字符是
'\0'
,以便使
Buffer2
在第14个字符处结束。然后我照你说的做了,在
sprintf(fileoutputname,“%s.txt”,str)中使用
Buffer2
作为
str
但它不起作用,甚至没有创建文件,这就是我尝试使用
sscanf
创建它的原因。使用
sscanf
效果很好,但问题是它以第一个空格字符结尾。查看代码,在我的代码示例中,您可能需要使用
fmemopen
将数据获取到文件指针
fp
<代码>文件*fp
fp=fmemopen(buffer2,strlen(buffer2),“r”)
fgets(buffer3200,fp)关闭(fp)将'buffer2'读入
buffer3
。仍将具有