簡體   English   中英

c字符串,char指針:需要幫助打印字符串和一些建議

[英]c strings, char pointers: need help printing the string and some advice

到目前為止,我有此代碼:

char *str;
scanf ("%s", &str);
printf("%s",&str);
system("pause");

它可以工作,但是問題是我按一個鍵繼續執行程序(或結束程序)后,出現以下錯誤:

運行時檢查失敗#2-變量'str'周圍的堆棧已損壞。

我以前從未玩過char指針,我想解釋一下為什么我會收到此錯誤以及如何改進其格式,我從用戶那里收到了字符串輸入。 我知道有更簡單的方法可以實現此目的,但是我的最終目標是獲得最簡單的代碼來確定輸入的大小,而不是限制用戶。

提前致謝

問題的第二部分(預先確定輸入的長度)用簡單的scanf是不可能的(除非變得更加復雜並逐塊讀取/追加)。

但是至少下面的代碼可以修復您對隨機存儲器的覆蓋。

char buffer[256];
char *str= buffer;
scanf ("%s", str);  // or scanf ("%s", buffer);  or scanf("%s", &buffer[0]);
printf("%s", str);  // or printf("%s", buffer);  or printf("%s", &buffer[0]);
system("pause");

您可以預先使用非常大的緩沖區,然后將結果修剪回給定的長度,但是您需要使用max。 開始的長度。

char *str= (char *)calloc(1,10000);
scanf ("%.9999s", str);
str= (char *)realloc(str, strlen(str)+1);  // release excess memory 
printf("%s", str); 
free(str);
system("pause");

你聲明str為指針,但你有沒有給它一個合法的位置指向 ; 它最初包含一些隨機值,該值可能是也可能不是可寫內存地址。 您仍然需要通過聲明數組或通過使用malloccalloc分配內存來分配足夠大的內存塊來容納您的輸入。

其次, %s轉換說明符期望相應的參數具有char *類型; 由於str具有該類型,因此您無需使用&運算符。

因此,您需要做類似的事情

char str[SOME_SIZE]; 

要么

char *str = malloc( SOME_SIZE );

其中SOME_SIZE足夠大,可以容納您輸入的字符串以及 0終止符的一個額外字符。

您將按以下方式讀取和寫入輸入:

scanf( "%s", str ); 
printf( "%s", str ); 

您不需要&來撥打任何電話。 %s轉換說明符期望相應的參數具有char *類型。 在大多數情況下1 ,數組類型的表達式將轉換為指針類型的表達式,並且表達式的值是數組中第一個元素的地址。 如果將str聲明為數組,則在scanfprintf調用中, 表達式 str 2將轉換為char * 如果將str聲明為char * ,則已經是預期的類型。

現在,輸出(通常)是行緩沖的,這意味着除非有換行符或字符串的長度超過緩沖區長度,否則它不會顯示在控制台上。 您將要在打印語句中添加換行符:

printf( "%s\n", str );

或在標准輸出流上調用fflush

printf( "%s", str );
fflush( stdout );

確保顯示您的輸出。


1-當數組表達式是sizeof的操作數時,將發生此規則的例外。 _Alignof或一元&運算符,或者是用於初始化聲明中另一個數組的字符串文字。

2-請記住,此轉換操作適用於表達式 ,而不適用於對象。 您有時會聽到有人聲稱“數組是指針”,但這不是事實。 數組和指針完全是不同的動物。

"my ultimate goal is to get the simplest code to determine the size of the input, and not limit the user."

是的,問題出在這里,一旦您這樣做,事情就會變得棘手。 您不能簡單地使用這樣的未初始化指針來獲取所需的“盡可能多”的字符。 最簡單的選項是:

char *str = malloc(1000);
scanf ("%999s", str);

要么

char str[1000];
scanf ("%999s", &str);

當然,這對輸入量施加了限制。 (順便說一句:您應該真正評估是否有滿足此條件的數字。)

現在還有其他選擇,但是它們開始不再是便攜式的。 如果您使用的是GCC,則可以使用“動態”規范:

char *str;
scanf("%ms", str); // dynamically allocate space for the size of input from the user

但是現在使用它可以將您的手與所使用的編譯器聯系在一起(也是該版本,該版本適用於c99,早期需要"%as"

除此之外,您可以一次讀取一個字符的輸入,並將其附加到自己成長的字符串中,但這是特定於操作系統的解決方案,因為您需要在* nix或_kbhit()上使用ncursesgetch()函數_kbhit()_getch(); 在風中。

Printf需要一個指針,而不是指向指針的地址。 您應該像這樣使用它:

 scanf("%s", str)
 printf("%s", str);



 char * str = malloc(100);  //allocates 100 bytes

 scanf("%###c", str) //Gets line from STDIN. ### indicates how many to read MAXIMUM, so scanf("%2c", str) will read maximum 2 characters into str.  Don't use s, since then you read until every whiteline.

 int i = 0;
 while(str[i] != NULL){

 i++;    

 }

 realloc(buf, i+1); //make the string fit tightly. I'm unsure if it will be null     terminated

//也許添加空終止//你必須確保他們不要嘗試

您正在掃描str而沒有先為其分配內存。 但是,幸運的是,它從一個隨機地址開始存儲,因此打印得很好,但是您的運行時系統認識到您遇到了沒有特權的存儲區。

解決方法如下:當無法獲取足夠的連續內存時,這將導致realloc失敗

 #include<stdio.h>
#include<malloc.h>
#define MAX 100
int main(){
    char *str=malloc(sizeof(char)*MAX);
    int size=0;
    int capacity=MAX;
    char c;
    int i=0;
    while((c=getchar())!='\n'){
        if(size==MAX-1){
            capacity=2*MAX;
            realloc(str,capacity);
        }
        str[i]=c;
        i++;
    }
    str[i]='\0';
    printf("%s",str);
    system("pause");    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM