简体   繁体   English

从 C 中的词干文件读取时出现问题

[英]Problem while reading from the stem file in C

I have a stem file named myfile , it has 2 sub files : myfile.data and myfile.names .我有一个名为myfile ,它有 2 个子文件: myfile.datamyfile.names

Now I want to write a code where it will first check the .names file's last line and see whether there is a zero or not, if there is any other number other than zero then it will say noisy data .现在我想写一个代码,它首先检查.names文件的最后一行,看看是否有零,如果有除零以外的任何其他数字,那么它会说noisy data And if the .names files last line has a zero, then I need to read the .data file and do some operations on that .data file to produce a valid output.而如果.names文件最后一行有一个零,然后我需要读取.data文件,并做一些操作.data文件产生有效的输出。

Now below I am giving what I have tried to do:现在下面我给出了我尝试做的事情:

    int main(int argc, char **argv)
    {
                char *path = argc > 1 ? argv[1] : "stdin";
                sprintf(path, "%s.names", argv[1]);
                
                
                FILE *in = argc > 1 ? xfopen(path, "r") : stdin;
                
                char buff[1024];
                int check = 0;

                fseek(in, 0, SEEK_SET); 

                while(!feof(in))
                {
                    memset(buff, 0x00, 1024); 
                    fscanf(in, "%[^\n]\n", buff);
                }
                
                if(strchr(buff, '0') != NULL){
                    check = 1;
                }
                
                if(check == 0){
                    printf("Noisy data...\n");
                }
                
                else if(check == 1){
                    
                    char *path = argc > 1 ? argv[1] : "stdin";
                    sprintf(path, "%s.data", argv[1]);
                    FILE *in = argc > 1 ? xfopen(path, "r") : stdin;
                    char buf[1024];
                    
                    if( fgets(buf, sizeof buf, in) == NULL ){
                        fputs("Input error\n", stderr);
                        return 1;
                    }
                    
                    ...
                    ...
                    produces the perfect output.
                }
            }
}

To execute this : <./executable_filename> <stemFileName> > <outputFileName>要执行此操作: <./executable_filename> <stemFileName> > <outputFileName>

So whenever I am doing : ./myFileName myfile output所以每当我做: ./myFileName myfile output

It is showing me : myfile.names.data: No such file or directory它向我展示: myfile.names.data: No such file or directory

Why is it happening?为什么会发生? Please help.请帮忙。

Here's an example which shows how to open the *.names file and includes logic to check if the final line of the file satisfies various properties.这是一个示例,它显示了如何打开*.names文件并包含用于检查文件的最后一行是否满足各种属性的逻辑。

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

int
main(int argc, char **argv)
{
    if( argc < 2 ){
        fprintf(stderr, "root filename required\n");
        return 1;
    }
    const char *base = argv[1];
    char input_path[PATH_MAX];
    snprintf(input_path, sizeof input_path, "%s.names", base);
    FILE *ifp = fopen(input_path, "r");
    if( ifp == NULL ){
        perror(input_path);
        return 1;
    }
    char buf[1024];
    /* Read the entire file one line at a time.  You could fseek to the
    end of the file and seek backwards to the start
    of the last line, but that seems to be an unnecessary
    complication for this example. */
    while( fgets(buf, sizeof buf, ifp) != NULL ){
        ;
    }
    /* When you get to the end, the last `fgets` returned NULL
    but did not write anything into buf, so buf contains the last
    line of the file */

    /* Check for read errors.
    ferror does not modify errno, but I can't find that
    in the language standard, so we'll make a copy.  Restoring
    errno ensures that `perror` reports the error that occurred
    during fgets rather than an error that occurs in the call to
    ferror.  This is probably overkill for this simple example.  It
    would be more important to check that `fgets` read a full line
    and handle that.  If the last line of the file is too large
    to fit in `buf`, the program should handle it; probably by aborting
    with an error message, but I don't know what you want to do in that
    case so I'm not bothering to check.
    */
    int errno_sav = errno;
    if( ferror(ifp) ){
        errno = errno_sav;
        perror(input_path);
        return 1;
    }

    puts("The last line is:");
    fputs(buf, stdout);
    /* Check if the last line contains a '0' */
    if( strchr(buf, '0') ){
        puts("The last line contains a 0");
    }
    /* Check if the last line is exactly the string "0\n" */
    if( strcmp(buf, "0\n") == 0 ){
        puts("The last contains nothing but a single 0");
    }

    char *end;
    /* Check if the last line is exactly some string representation
    of the integer 0.  (ie, "0000\n"  "0x0") */
    if( strtol(buf, &end, 0) == 0 && end != buf && *end == '\n'){
        puts("The last line is the integer 0");
    }
    return EXIT_SUCCESS;
}

Note that you might want to check that snprintf had enough space to write the filename, but that is not practically necessary.请注意,您可能想要检查snprintf是否有足够的空间来写入文件名,但这实际上并不是必需的。 If the path is so long that it is an issue, the fopen will fail and you'll get a decent error message.如果路径太长以至于出现问题,fopen 将失败,您将收到一条不错的错误消息。 It is possible that this will cause your program to incorrectly process a file with a truncated name like ...bas.nam , and it might be a good exercise to learn how to deal with that.这可能会导致您的程序错误地处理名称被截断的文件,例如...bas.nam ,学习如何处理它可能是一个很好的练习。

char *path = argc > 1 ? argv[1] : "stdin";
sprintf(path, "%s.names", argv[1]);

path is declared as string literal "stdin" , you can't change it anymore (and why would you want to?) If path is a pointer to argv[1] , then argv[1] should be left alone. path被声明为字符串文字"stdin" ,你不能再改变它(你为什么要改变它?)如果path是一个指向argv[1]的指针,那么argv[1]应该保持不变。

You can use the debugger or add printf("path = %s\\n", path) to test what you have.您可以使用调试器或添加printf("path = %s\\n", path)来测试您拥有的内容。

if ((in = fopen(path, "r")) != NULL) 

You don't have any error check if fopen succeeded.如果fopen成功,您没有任何错误检查。 Here is a simple program to open a file based on argv[1] , I don't know how you want to handle fout这是一个基于argv[1]打开文件的简单程序,我不知道你想如何处理fout

int main(int argc, char** argv)
{
    FILE* fin = stdin;
    FILE* fout = NULL;

    char buf[1024];
    if (argc > 1)
    {
        sprintf(buf, "%s.name", argv[1]);
        printf("path = %s\n", buf);
        fin = fopen(buf, "r");
        if (!fin) { printf("can't open %s\n", buf); return 0; }
        printf("success\n");
    }
    
    while (fgets(buf, sizeof buf, fin)) 
        printf("%s", buf);

    if (fin) fclose(fin);
    if (fout) fclose(fout);
    return 0;
}

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

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