简体   繁体   English

当我不知道它将在C中分配多少个值时,我该如何使用scanf?

[英]How do I use scanf when I dont know how many values it will assign in C?

These are the instructions: "Read characters from standard input until EOF (the end-of-file mark) is read. Do not prompt the user to enter text - just read data as soon as the program starts." 这些是指令:“从标准输入中读取字符,直到读取EOF(文件结束标记)。不要提示用户输入文本-程序启动后立即读取数据。”

So the user will be entering characters, but I dont know how many. 因此用户将输入字符,但我不知道有多少个字符。 I will later need to use them to build a table that displays the ASCII code of each value entered. 稍后,我将需要使用它们来构建一个表,该表显示每个输入值的ASCII码。

How should I go about this? 我应该怎么做?

This is my idea 这是我的主意

int main(void){
     int inputlist[], i = -1;
     do {++i;scanf("%f",&inputlist[i]);}
         while(inputlist[i] != EOF)

You said character.So this might be used 您说的是字符,因此可以使用

char arr[10000];
ch=getchar();
while(ch!=EOF)
{
   arr[i++]=ch;
   ch=getchar();
}
//arr[i]=0; TO make it a string,if necessary.

And to convert to ASCII 并转换为ASCII

for(j=0;j<i;j++)
     printf("%d\n",arr[j]);

If you are particular in using integer array,Use 如果您特别喜欢使用整数数组,请使用

int arr[1000];
while(scanf("%d",&arr[i++])!=EOF);

PPS:This works only if your input is one character per line. PPS:仅当您输入的内容为每行一个字符时,此方法才有效。

scanf returns EOF on EOF scanfEOF上返回EOF

You have a reasonable attempt at a start to the solution, with a few errors. 您有一个合理的尝试开始解决方案,但有一些错误。 You can't define an array without specifying a size, so int inputlist[] shouldn't even compile. 您不能在不指定大小的情况下定义数组,因此int inputlist[]甚至不应该编译。 Your scanf() specifier is %f for float, which is wrong twice (once because you declared inputlist with an integer type, and twice because you said your input is characters, so you should be telling scanf() to use %c or %s ), and really if you're reading input unconditionally until EOF , you should use an unconditional input function, such as fgets() or fread() . 您的scanf()说明符是%f用于float,这是错误的两次(一次是因为您用整数类型声明了inputlist ,一次是因为您说输入是字符,所以两次了,所以应该告诉scanf()使用%c%s ),实际上,如果您在EOF之前无条件地读取输入,则应该使用无条件的输入函数,例如fgets()fread() (or read() , if you prefer). (如果您愿意,也可以使用read() )。

You'll need two things: A place to store the current chunk of input, and a place to store the input that you've already read in. Since the input functions I mentioned above expect you to specify the input buffer, you can allocate that with a simple declaration. 您将需要两件事:一个用于存储当前输入大块的位置,以及一个用于存储已读入输入的位置。由于我上面提到的输入函数希望您指定输入缓冲区,因此您可以分配一个简单的声明。

char input[1024];

However, for the place to store all input, you'll want something dynamically allocated. 但是,对于存储所有输入的位置,您将需要动态分配一些内容。 The simplest solution is to simply malloc() a chunk of storage, keep track of how large it is, and realloc() it if and when necessary. 最简单的解决方案是简单地malloc()一块存储,跟踪它的大小,并在必要时重新realloc()它。

char *all_input;
int poolsize=16384;
all_input = malloc(pool_size);

Then, just loop on your input function until the return value indicates that you've hit EOF, and on each iteration of the loop, append the input data to the end of your storage area, increment a counter by the size of the input data, and check whether you're getting too close to the size of your input storage area. 然后,对输入函数进行循环,直到返回值表明您已达到EOF,然后在循环的每次迭代中,将输入数据附加到存储区域的末尾,使计数器增加输入数据的大小,然后检查您是否太接近输入存储区的大小。 (And if you are, then use realloc() to grow your storage.) (如果是,则使用realloc()增加存储空间。)

You could read the input by getchar until reach EOF. 您可以通过getchar读取输入,直到达到EOF。 And you don't know the size of input, you should use dynamic size buffer in heap. 而且您不知道输入的大小,应该在堆中使用动态大小缓冲区。

char *buf = NULL;
long size  = 1024;
long count = 0;
char r;

buf = (char *)malloc(size);
if (buf == NULL) {
    fprintf(stderr, "malloc failed\n");
    exit(1);
}   

while( (r = getchar()) != EOF) {
    buf[count++] = r;
    // leave one space for '\0' to terminate the string 
    if (count == size - 1) {
        buf = realloc(buf,size*2);
        if (buf == NULL) {
            fprintf(stderr, "realloc failed\n");
            exit(1);
        }   
        size = size * 2;
    }   
}   
buf[count] = '\0';
printf("%s \n", buf);

return 0;

Here is full solution for your needs with comments. 这是您有意见的完整解决方案。

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

// Number of elements
#define CHARNUM 3

int main(int argc, char **argv) {
    // Allocate memory for storing input data
    // We calculate requested amount of bytes by the formula:
    // NumElement * SizeOfOneElement
    size_t size = CHARNUM * sizeof(int);

    // Call function to allocate memory
    int *buffer = (int *) calloc(1, size);

    // Check that calloc() returned valid pointer
    // It can: 1. Return pointer in success or NULL in faulire
    //         2. Return pointer or NULL if size is 0 
    //            (implementation dependened). 
    //            We can't use this pointer later.

    if (!buffer || !size)
    {
        exit(EXIT_FAILURE);
    }

    int curr_char;
    int count = 0;
    while ((curr_char = getchar()) != EOF)
    {
        if (count >= size/sizeof(int))
        {
            // If we put more characters than now our buffer
            // can hold, we allocate more memory
            fprintf(stderr, "Reallocate memory buffer\n");
            size_t tmp_size = size + (CHARNUM * sizeof(int));
            int *tmp_buffer = (int *) realloc(buffer, tmp_size);
            if (!tmp_buffer)
            {
                fprintf(stderr, "Can't allocate enough memory\n");
                exit(EXIT_FAILURE);
            }
            size = tmp_size;
            buffer = tmp_buffer;
        }
        buffer[count] = curr_char;
        ++count;
    }


    // Here you get buffer with the characters from 
    // the standard input
    fprintf(stderr, "\nNow buffer contains characters:\n");
    for (int k = 0; k < count; ++k)
    {
        fprintf(stderr, "%c", buffer[k]);
    }
    fprintf(stderr, "\n");

    // Todo something with the data

    // Free all resources before exist
    free(buffer);
    exit(EXIT_SUCCESS); }

Compile with -std=c99 option if you use gcc. 如果使用gcc,请使用-std=c99选项进行编译。

Also you can use getline() function which will read from standard input line by line. 您也可以使用getline()函数,该函数将从标准输入中逐行读取。 It will allocate enough memory to store line. 它将分配足够的内存来存储行。 Just call it until End-Of-File. 只需调用它直到文件结束即可。

errno = 0; 
int read = 0; 
char *buffer = NULL;
size_t len = 0;
while ((read = getline(&buffer, &len, stdin)) != -1) 
{ // Process line } 

if (errno) { // Get error }

// Process later

Note that if you are using getline() you should anyway use dynamic allocated memory. 请注意,如果您使用的是getline() ,则无论如何都应使用动态分配的内存。 But not for storing characters, rather to store pointers to the strings. 但不是用于存储字符,而是用于存储指向字符串的指针。

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

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