【问题标题】:Redirecting input(text file) in C在C中重定向输入(文本文件)
【发布时间】:2017-03-23 20:43:32
【问题描述】:

所以我似乎无法重定向输入以便我的程序读取它。

它在作业中说程序不应该打印任何东西来提示用户输入。由于必须从标准输入读取许多数字来测试您的程序,因此您应该使用 INPUT REDIRECTION 从文件中读取输入。

我有这个主要功能:

int main(int argc, char const *argv[])
{
    int arr[100];
    for (int i = 0; i < SIZE; i++)
    {
        values[i] = 0;
        hashMapLinear[i] = 0;             
    }
    FILE* file = fopen("file_name.txt", "r");             
    int index = 0;
    int k = 0;
    while (!feof(file))
    {
        fscanf(file, "%d", &k);
        arr[index] = k;
        index++;
    }
    fclose(file);
    file = fopen("file_name.txt", "r");
    int i = 0;
    fscanf(file, "%d", &i);
    float size = i;

    fscanf(file, "%d", &i);
    int thresh_hold = i;

    int load_factor = size / 2;
    int j = 0;

    if (size <= 0)
    {
            printf("\nSize of file can not be zero or negative integer:\n");
    }
    else
    {
        while (!feof(file))
        {
            if (num_keys <= load_factor)
            {
                int check_valid_input= fscanf(file, "%d", &i);      
                if (check_valid_input != 0 || check_valid_input== -1)
                {
                    insert_into_hashtable(i, size);
                }
                else
                {
                      printf("\n invalid input:\n");
                      exit(1);
                }
            }
            else
            {
                printf("\nError in inserting more numbers:\n");
                exit(1);
            }
        }
        fclose(file);
        printHashMap(arr,size, thresh_hold);                  
    }
}

如何编辑这个 main 函数,以便将 seq.1 或任何其他文本文件重定向到 C 程序?任何帮助将不胜感激!

【问题讨论】:

  • 使用fscanf的stdin-reading兄弟scanf
  • 您将其更改为从stdin 读取,它在您的程序启动时已经打开。您根本不必致电fopen。当您键入 ./a.out &lt; seq.1 时,重定向由 shell 在程序外部完成。
  • 永远不要使用feof() 来控制while() 循环,该函数不能像发布的代码所期望的那样工作。还需要避免数组溢出建议:while ( index &lt; 100 &amp;&amp; 1 == fscanf(file, "%d", &amp;k) ) {
  • 由于代码关闭和重新打开同一个文件都使用“r”模式,强烈建议将第一次调用fclose()和第二次调用fopen()替换为调用@987654330 @
  • 编译时,始终启用所有警告,然后修复这些警告。 (对于gcc,至少使用:-Wall -Wextra -pedantic 我也使用:-Wconversion -std=gnu11

标签: c input file-io


【解决方案1】:

只需使用stdin而不是file,但不要打开stdin,也不要关闭它。

当调用像./program &lt; seq.1这样的程序时,操作系统会将seq.1的内容传递给你的程序,就好像它是通过控制台输入的一样。因此,使用代表控制台输入的stdin 就可以完成这项工作。

注意stdin在你的程序启动时默认已经打开。

【讨论】:

    【解决方案2】:

    您的代码对输入文件进行了硬编码,因此命令行中的文件重定向不会执行任何操作。文件重定向有助于 stdin(控制台输入)、stdout(控制台输出)和 stderr(控制台错误消息输出)。有关教程,请参见 linuxcommand.org here

    因此,要使您的代码与标准输入一起工作,请使用 scanf 而不是 fscanf。 scanf 从 FILE 标准输入获取输入,而 fscanf 从指定的 FILE 获取输入。使用 scanf 将导致来自 stdin 的输入,可以如上所述在命令行上重定向。同样,如果要使用 stdout,请使用 printf 而不是 fprintf。 scanf 和 printf 都不带文件参数,但在其他方面与 fscanf 和 fprint 相同。更多解释请参见thisstackOverflow 文章。

    以下是我将如何修复您的代码以读取/写入标准输入和标准输出:

    #include <stdio.h>
    int main(int argc, char const *argv[])
    {
        int arr[400];
        for (int i = 0; i < SIZE_HASH_MAP; i++)
        {
            values[i] = 0;
            hashMapLinear[i] = 0;             
        }
        // Not Needed: FILE* file = fopen("file_name.txt", "r");             
        int index = 0;
        int k = 0;
        while (!feof(stdin))
        {
            scanf("%d", &k);
            arr[index] = k;
            index++;
        }
        // fclose(file);
        // file = fopen("file_name.txt", "r");
        int i = 0;
        scanf("%d", &i);
        float size = i;
        //printf("%d ", i);
        scanf("%d", &i);
        int thresh_hold = i;
        //printf("%d ", i);
        int load_factor = size / 2;
        int j = 0;
        //int check_valid_input = 0;
        if (size <= 0)
        {
                printf("\nSize of file can not be zero or negative integer:\n");
        }
        else
        {
            while (!feof(stdin))
            {
                if (num_keys <= load_factor)
                {
                    int check_valid_input= scanf("%d", &i);      
                    if (check_valid_input != 0 || check_valid_input== -1)
                    {
                        insert_into_hashtable(i, size);
                    }
                    else
                    {
                          printf("\n invalid input:\n");
                          exit(1);
                    }
                }
                else
                {
                    printf("\nError in inserting more numbers:\n");
                    exit(1);
                }
            }
            // fclose(file);
            printHashMap(arr,size, thresh_hold);                  
        }
    }
    

    要使用标准输入(和文件重定向),您将无法关闭并重新打开标准输入并获得相同的数据。它只是不能那样工作。因此,请删除其中一个读取循环,以便您只读取一次。第一个循环将其读入数组 arr[],因此第二个循环应该从该数组中获取值,而不是重新读取它。

    #include <stdio.h>
    $include <stdlib.h>
    int main(int argc, char const *argv[])
    {
        int arr[400];
        for (int i = 0; i < SIZE_HASH_MAP; i++)
        {
            values       [i] = 0;
            hashMapLinear[i] = 0;             
        }
    
        int index = 0;
        int k     = 0;
        while (!feof(stdin))
        {
            scanf("%d", &k);
            arr[index] = k;
            index++;
        }
    
        float size      = arr[0];
        int thresh_hold = arr[1];
        int load_factor = size / 2;
        int j = 0;
    
        if (size <= 0)
        {
          printf("\nSize of file can not be zero or negative integer:\n");
          exit(-1);
        }
        else
        {
         int i;
         for(i=2; i<index; i++) // reuse values stored in arr[]
            insert_into_hashtable(arr[i], size);
         printHashMap(arr,size, thresh_hold);                  
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可能想要使用 open() 而不是 fopen()。 Open 返回一个非负整数,表示编号最小的未使用文件描述符。使用文件描述符可以更轻松地重定向输出。

      【讨论】:

        【解决方案4】:

        shell 命令已经将输入重定向到您的程序。在您的程序中已经打开了一个名为 stdin 的文件指针,它代表标准输入。当您使用&lt; seq.1 时,它会将文件的内容通过管道传输到程序的标准输入中,您可以使用 fgetc 或 scanf 读取这些内容。

        int main(int argc, char const *argv[])
        {
            int arr[400];
            for (int i = 0; i < SIZE_HASH_MAP; i++)
            {
                values[i] = 0;
                hashMapLinear[i] = 0;             
            }
        
            int index = 0;
            int k = 0;
            while (!feof(stdin))
            {
                fscanf(stdin, "%d", &k);
                arr[index] = k;
                index++;
            }
        }
        

        此程序从标准输入中读取所有数字并将它们存储在您的数组中。请注意,您无需打开或关闭它,当您的 main 被调用并在程序执行结束时关闭时,它已经打开。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-21
          • 2021-03-09
          • 1970-01-01
          • 2013-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-08
          相关资源
          最近更新 更多