简体   繁体   English

为什么我的 C 程序没有打印出字符串?

[英]Why is my C program not printing out the string?

I am am making a program that prints out what the user types in, and it needs to be done with the method read_line() (for my homework), so I can't change too much.我正在制作一个程序来打印出用户输入的内容,并且需要使用read_line()方法(对于我的作业)来完成,所以我不能改变太多。

I don't understand why it isn't printing out what the user enters.我不明白为什么它没有打印出用户输入的内容。

#include <stdlib.h>

char *read_line(char *buf, size_t sz) {
  char tempBuf[sz];
  char c;
  int pos = 0;

  printf("> ");

  while(1) {
    c = getchar();
    if (tempBuf[pos] == EOF || tempBuf[pos] == '\n') {
      buf = tempBuf;
      return buf;
    } else {
      tempBuf[pos] = c;
    }
    pos++;
  }
}

int main(int argc, char **argv) {
  char *buf;
  char *input = read_line(buf, 128);

  printf("Here: %s", input);
}

I am new to C and I am finding it very confusing, so please explain anything in pretty simple terms.我是 C 的新手,我发现它非常混乱,所以请用非常简单的术语解释任何事情。 Any help would be much appreciated.任何帮助将非常感激。

char *buf;
char *input = read_line(buf, 128);

Your first line creates a pointer variable called buf but does not assign it any particular value.您的第一行创建了一个名为buf的指针变量,但没有为其分配任何特定值。 Your second line passes the value of buf to read_line -- but you never assigned it any particular value.您的第二行将buf的值传递给read_line - 但您从未为其分配任何特定值。 So you passed garbage to read_line and told it to use that garbage as a buffer.因此,您将垃圾传递给read_line并告诉它使用该垃圾作为缓冲区。

You might want char buf[128];你可能想要char buf[128]; instead of char *buf;而不是char *buf; , but it's hard to tell. ,但很难说。

Also, please see my comment about your read_line function being broken in a way that indicates that whoever wrote it does not understand how to use getchar .另外,请参阅我关于您的read_line function 被破坏的评论,这表明编写它的人不了解如何使用getchar

There are many mistakes in your program.你的程序有很多错误。

For starters you are passing to the function an uninitialized pointer对于初学者,您将一个未初始化的指针传递给 function

char *buf;
char *input = read_line(buf, 128);

In fact there is no sense to pass the pointer value of which is not used in the function.实际上,传递 function 中未使用的指针值是没有意义的。

Within the function the variable c should be declared as having the type int.在 function 中,变量 c 应声明为具有 int 类型。

int c;

Otherwise if the type char behaves as the type unsigned char (it depends on a compiler option) a comparison it with EOF will always evaluates to false.否则,如果 char 类型表现为 unsigned char 类型(它取决于编译器选项),则它与EOF的比较将始终评估为 false。

Within the function the array tempBuf is not initialized.在 function 中,数组 tempBuf 未初始化。 So this if statement所以这个 if 语句

if (tempBuf[pos] == EOF || tempBuf[pos] == '\n') {

invokes undefined behavior.调用未定义的行为。

Within the wjile llop you have to check that the value of pos is less than the value of sz .在 wjile llop 中,您必须检查pos的值是否小于sz的值。

The function returns a pointer to a local array that makes the returned pointer invalid. function 返回一个指向本地数组的指针,使返回的指针无效。

  buf = tempBuf;
  return buf;

Moreover the array even does not contain a string because the terminating zero is not appended to the array.此外,该数组甚至不包含字符串,因为终止零未附加到数组中。

The function should allocate dynamically memory and return pointer to the allocated memory that will contain a zero terminated string. function 应动态分配 memory 并返回指向已分配 memory 的指针,该指针将包含一个以零结尾的字符串。

Below there is a demonstrative program that shows how the function can be written.下面是一个演示程序,显示了如何编写 function。

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

char * read_line( size_t n ) 
{
    char *s = malloc( n );

    if ( s != NULL )
    {
        int c;

        printf( "> " );

        size_t i = 0;

        for ( ; i + 1 < n && ( c = getchar() ) != EOF && c != '\n'; i++ )
        {
            s[i] = c;
        }

        s[i] = '\0';
    }

    return s;
}

int main(void) 
{
    size_t n = 128;

    char *input = read_line( n );

    if ( input != NULL ) printf( "Here: %s\n", input );

    free( input );

    return 0;
}

the program output might look like程序 output 可能看起来像

> Hello Jake Jackson
Here: Hello Jake Jackson

The current implementation of read_line is very flawed due to the simple fact that it returns a locally declared buffer (which gets deleted at the end of the function). read_line的当前实现存在很大缺陷,因为它返回一个本地声明的缓冲区(在函数末尾被删除)。 As a result, your pointers are pointing at garbage values (which is very dangerous - I repeat - as it will cause your program to crash or worse [keep running even when using memory it doesn't own]).结果,您的指针指向垃圾值(这是非常危险的 - 我重复一遍 - 因为它会导致您的程序崩溃或更糟[即使使用它不拥有的 memory 也继续运行])。

What you should be doing instead a dynamically creating the buffer on the heap (that way it can safely be returned - but it would have to be manually deleted).应该做的是在堆上动态创建缓冲区(这样可以安全地返回它 - 但必须手动删除它)。

So your function (and the rest of the code) should change to something like the following:因此,您的 function (以及代码的 rest )应更改为如下所示:

#include <stdlib.h>

char *read_line(size_t sz) {
  // create a new buffer on the heap - so it can easily be returned (note this will have to be deleted after use using free()).
  char *tempBuf = malloc(sz);
  int c;
  int pos = 0;

  // set all elements of tempBuf to nulls
  memset(arr, 0, sz); 

  printf("> ");

  while(1) {
    c = getchar();
    if (tempBuf[pos] == EOF || tempBuf[pos] == '\n') {
      return tempBuf;
    } else {
      tempBuf[pos] = (char) c;
    }
    pos++;
  }
}

int main(int argc, char **argv) {
  char *input = read_line(128);    
  printf("Here: %s", input);

  // free the memory since we are now done with it.
  free(input);
}

You can read more about the heap & stack here .您可以在此处阅读有关堆和堆栈的更多信息。

There are a few issues with your program.您的程序存在一些问题。

In your main() , you initialize buf , but never allocate any memory for it.在您的main()中,您初始化buf ,但从不为其分配任何 memory 。 You can allocate memory using malloc :您可以使用malloc

    char *buf = malloc(128);
    char *input = read_line(buf, 128);

In read_line() , you initialise tempBuf , but read an element from it before initialising the element.read_line()中,您初始化tempBuf ,但在初始化元素之前从中读取一个元素。 tempBuf holds junk values, which you use for comparisons. tempBuf包含用于比较的垃圾值。 You initialise the element after the comparison, which is not correct.您在比较初始化元素,这是不正确的。 There are other issues as well.还有其他问题。

Here is a modified version with minimal changes to your code:这是一个修改后的版本,对您的代码进行了最小的更改:

char *read_line(char *buf, size_t sz) {
  char *tempBuf = malloc(sz);
  char c;
  int pos = 0;

  printf("> ");

  while(1) {
    c = getchar();
    if (c == '\n') {
      tempBuf[pos] = '\0';
      buf = tempBuf;
      return buf;
    } else {
      tempBuf[pos] = c;
    }
    pos++;
  }
}

The last character of any string in C needs to be a null character ('\0'). C 中任何字符串的最后一个字符必须是 null 字符('\0')。

Tip: You should also add a check for pos , so it doesn't exceed the value of sz .提示:您还应该添加对pos的检查,因此它不会超过sz的值。

Try this one:试试这个:

#include<stdio.h>       //originally missing - needed for I/O
#include<string.h>      //for memset

void read_line(char *buf, size_t sz) 
{
   char c;
   int pos = 0;

   printf("> ");

   while(pos<sz-1) 
   {
       c = getchar();
       if (c == EOF || c == '\n')  //originally tempBuf[pos] was used which contained garbage value
       {
           break;
       } 
       else 
       {
           buf[pos] = c;
       }
       pos++;
   }
}

 int main(int argc, char **argv) 
 {
    char buf[128];             //buf is now an array instead of char*
    memset(buf,'\0',128);
    read_line(buf, 128);    //buf is the array in this code as the array tempBuf is local and will be destroyed once we come out of read_line function 

    printf("Here: %s", buf);
 }

Errors have been commented in this code.此代码中已对错误进行了注释。

You have so many errors.你有很多错误。 Local variables used outside the scope, not terminated strings etc etc. Here you have working example https://godbolt.org/z/_3ZHUJ在 scope 之外使用的局部变量,未终止的字符串等。这里有工作示例https://godbolt.org/z/_3ZHUJ

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

char *read_line(size_t sz) 
{
  char *tempBuf = malloc(sz);
  char c;
  int pos = 0;

  printf("> ");

  while(1) {
    c = getchar();
      tempBuf[pos] = c;
    if (tempBuf[pos] == EOF || tempBuf[pos] == '\n') 
    {
      tempBuf[pos] = 0;
      return tempBuf;
    }
    pos++;
  }
}

int main(int argc, char **argv) {
  char *buf;
  char *input = read_line( 128);

  printf("Here: %s", input);
}

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

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