Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.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
C语言编程中的文件处理问题_C_Filehandle - Fatal编程技术网

C语言编程中的文件处理问题

C语言编程中的文件处理问题,c,filehandle,C,Filehandle,我想从给定的输入文件中逐行读取,处理每一行(即它的字),然后转到另一行 所以我使用fscanf(fptr,“%s”,words)来读取单词,当它遇到行尾时应该停止 但这在fscanf是不可能的,我想。。。所以请告诉我怎么做 我应该阅读给定行中的所有单词(即遇到行尾)以终止,然后转到另一行,并重复相同的过程。使用。是的,链接是到cplusplus的,但它源于cstdio.h 您也可以使用sscanf()从字符串中读取单词,或者只使用strtok()将它们分开 作为对注释的响应:fgets()(将

我想从给定的输入文件中逐行读取,处理每一行(即它的字),然后转到另一行

所以我使用fscanf(fptr,“%s”,words)来读取单词,当它遇到行尾时应该停止

但这在fscanf是不可能的,我想。。。所以请告诉我怎么做

我应该阅读给定行中的所有单词(即遇到行尾)以终止,然后转到另一行,并重复相同的过程。

使用。是的,链接是到cplusplus的,但它源于c
stdio.h

您也可以使用
sscanf()
从字符串中读取单词,或者只使用
strtok()
将它们分开


作为对注释的响应:
fgets()
(将
\n
保留在字符串中)的这种行为允许您确定是否遇到了实际的行尾。请注意,如果提供的缓冲区不够大,
fgets()
也可能只读取文件中的部分行。在您的情况下-只需检查最后的
\n
,如果您不需要它,请将其删除。大概是这样的:

// actually you'll get str contents from fgets()
char str[MAX_LEN] = "hello there\n";
size_t len = strlen(str);
if (len && str[len-1] == '\n') {
    str[len-1] = 0;
}

就这么简单。

考虑到所有stdio函数中固有的缓冲,我很想用getc()逐个字符地读取流。一个简单的有限状态机可以识别单词边界,如果需要,还可以识别行边界。一个优点是完全没有要溢出的缓冲区,除了在进一步处理需要时收集当前字的缓冲区之外

您可能想做一个快速的基准测试,比较使用getc()和fgets()完全读取大文件所需的时间

如果外部约束要求每次读取一行文件(例如,如果需要处理来自tty的面向行的输入),那么fgets()可能是您的朋友,正如其他答案所指出的,但即使是getc()也是如此只要输入流在线路缓冲模式下运行(如果stdin在tty上,这对于stdin是常见的),这种方法就可以接受

编辑:要控制输入流上的缓冲区,可能需要调用setbuf()或setvbuf()将其强制为缓冲模式。如果输入流最终没有缓冲,那么使用某种形式的显式缓冲区总是比原始流上的getc()快

最好的性能可能是使用一个与磁盘I/O相关的缓冲区,至少两个磁盘块大小,可能远不止这些。通常,即使是这种性能也可以通过将输入安排为内存映射文件,并在处理文件时依赖内核的分页来读取和填充缓冲区,就像处理一个巨大的字符串一样

不管选择如何,如果性能很重要,那么您将需要对几种方法进行基准测试,并选择在您的平台中最有效的方法。即使如此,如果你的问题得到了编写、调试和使用,那么最简单的表达仍然可能是最好的整体答案

但这在fscanf中是不可能的

是的,有点邪恶;)

更新:更多关于邪恶的澄清

但不幸的是有点错误。我假设
[^\n]%*[^\n]
应该是
[^\n]%*
。此外,需要注意的是,这种方法将删除行中的空白蜻蜓

请注意,
xstr(MAXLINE)[^\n]
读取的
MAXLINE
字符可以是除换行符以外的任何字符(即
\n
)。如果行包含超过
最大行
个字符,但不包括换行符,则说明符的第二部分,即
*[^\n]
拒绝任何内容(这就是
*
字符存在的原因)。换行符告诉
scanf
停止匹配。如果我们按照蜻蜓的建议去做呢?唯一的问题是
scanf
将不知道在哪里停止,并将一直抑制赋值,直到下一个换行符被点击(这是第一部分的另一个匹配项)。因此,在报告时,您将跟踪一行输入

如果你想循环阅读呢?需要稍加修改。我们需要添加一个
getchar()
来使用不匹配的换行符。代码如下:

#include <stdio.h>

#define MAXLINE 255

/* stringify macros: these work only in pairs, so keep both */
#define str(x) #x
#define xstr(x) str(x)

int main() {
    char line[ MAXLINE + 1 ];
    /* 
       Wickedness explained: we read from `stdin` to `line`.
       The format specifier is the only tricky part: We don't
       bite off more than we can chew -- hence the specification 
       of maximum number of chars i.e. MAXLINE. However, this
       width has to go into a string, so we stringify it using  
       macros. The careful reader will observe that once we have
       read MAXLINE characters we discard the rest upto and
       including a newline.
     */
    int n = fscanf(stdin, "%" xstr(MAXLINE) "[^\n]%*[^\n]", line);
    if (!feof(stdin)) {
        getchar();
    }
    while (n == 1) {
        printf("[line:] %s\n", line);
        n = fscanf(stdin, "%" xstr(MAXLINE) "[^\n]%*[^\n]", line);
        if (!feof(stdin)) {
            getchar();
        }
    } 
    return 0;
}
#包括
#定义MAXLINE 255
/*stringify宏:这些宏只能成对工作,所以两者都要保留*/
#定义str(x)#x
#定义xstr(x)str(x)
int main(){
字符行[MAXLINE+1];
/* 
邪恶解释:我们从'stdin'读到'line'。
格式说明符是唯一棘手的部分:我们没有
咬掉比我们能咀嚼的更多的东西——这就是规格
最大字符数,即MAXLINE。但是
宽度必须变成一个字符串,所以我们使用
宏。仔细的读者会注意到,一旦我们
读取MAXLINE字符,我们丢弃其余字符,直到
包括一条新线。
*/
int n=fscanf(stdin,“%”xstr(MAXLINE)“[^\n]%*[^\n]”,第行);
如果(!feof(stdin)){
getchar();
}
而(n==1){
printf(“[line:][s\n”,第行);
n=fscanf(stdin,“%”xstr(MAXLINE)“[^\n]%*[^\n]”,第行);
如果(!feof(stdin)){
getchar();
}
} 
返回0;
}

如果您在使用GNU扩展的系统上工作,有一种叫做getline(man 3 getline)的东西,它允许您逐行读取文件,而getline会在需要时为您分配额外的内存。手册页包含一个示例,我修改了该示例,使用strtok(man3strtrok)拆分该行

#包括
#包括
内部主(空)
{
文件*fp;
char*line=NULL;
尺寸长度=0;
阅读;
fp=fopen(“/etc/motd”,“r”);
如果(fp==NULL)
{
printf(“文件打开失败\n”);
返回0;
}
while((read=getline(&line,&len,fp))!=-1){
//在这一点上,我们有一个李
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen("/etc/motd", "r");
    if (fp == NULL)
    {
        printf("File open failed\n");
        return 0;
    }

    while ((read = getline(&line, &len, fp)) != -1) {
        // At this point we have a line held within 'line'
        printf("Line: %s", line);
        const char * delim = " \n";
        char * ptr; 
        ptr = (char * )strtok(line,delim);

        while(ptr != NULL)
        {
            printf("Word: %s\n",ptr);
            ptr = (char *) strtok(NULL,delim);
        }
    }

    if (line)
    {
        free(line);
    }
    return 0;
}