簡體   English   中英

為什么我的 C 程序沒有打印出字符串?

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

我正在制作一個程序來打印出用戶輸入的內容,並且需要使用read_line()方法(對於我的作業)來完成,所以我不能改變太多。

我不明白為什么它沒有打印出用戶輸入的內容。

#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);
}

我是 C 的新手,我發現它非常混亂,所以請用非常簡單的術語解釋任何事情。 任何幫助將非常感激。

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

您的第一行創建了一個名為buf的指針變量,但沒有為其分配任何特定值。 您的第二行將buf的值傳遞給read_line - 但您從未為其分配任何特定值。 因此,您將垃圾傳遞給read_line並告訴它使用該垃圾作為緩沖區。

你可能想要char buf[128]; 而不是char *buf; ,但很難說。

另外,請參閱我關於您的read_line function 被破壞的評論,這表明編寫它的人不了解如何使用getchar

你的程序有很多錯誤。

對於初學者,您將一個未初始化的指針傳遞給 function

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

實際上,傳遞 function 中未使用的指針值是沒有意義的。

在 function 中,變量 c 應聲明為具有 int 類型。

int c;

否則,如果 char 類型表現為 unsigned char 類型(它取決於編譯器選項),則它與EOF的比較將始終評估為 false。

在 function 中,數組 tempBuf 未初始化。 所以這個 if 語句

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

調用未定義的行為。

在 wjile llop 中,您必須檢查pos的值是否小於sz的值。

function 返回一個指向本地數組的指針,使返回的指針無效。

  buf = tempBuf;
  return buf;

此外,該數組甚至不包含字符串,因為終止零未附加到數組中。

function 應動態分配 memory 並返回指向已分配 memory 的指針,該指針將包含一個以零結尾的字符串。

下面是一個演示程序,顯示了如何編寫 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;
}

程序 output 可能看起來像

> Hello Jake Jackson
Here: Hello Jake Jackson

read_line的當前實現存在很大缺陷,因為它返回一個本地聲明的緩沖區(在函數末尾被刪除)。 結果,您的指針指向垃圾值(這是非常危險的 - 我重復一遍 - 因為它會導致您的程序崩潰或更糟[即使使用它不擁有的 memory 也繼續運行])。

應該做的是在堆上動態創建緩沖區(這樣可以安全地返回它 - 但必須手動刪除它)。

因此,您的 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);
}

您可以在此處閱讀有關堆和堆棧的更多信息。

您的程序存在一些問題。

在您的main()中,您初始化buf ,但從不為其分配任何 memory 。 您可以使用malloc

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

read_line()中,您初始化tempBuf ,但在初始化元素之前從中讀取一個元素。 tempBuf包含用於比較的垃圾值。 您在比較初始化元素,這是不正確的。 還有其他問題。

這是一個修改后的版本,對您的代碼進行了最小的更改:

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++;
  }
}

C 中任何字符串的最后一個字符必須是 null 字符('\0')。

提示:您還應該添加對pos的檢查,因此它不會超過sz的值。

試試這個:

#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);
 }

此代碼中已對錯誤進行了注釋。

你有很多錯誤。 在 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