[英]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
為指針,但你有沒有給它一個合法的位置指向 ; 它最初包含一些隨機值,該值可能是也可能不是可寫內存地址。 您仍然需要通過聲明數組或通過使用malloc
或calloc
分配內存來分配足夠大的內存塊來容納您的輸入。
其次, %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
聲明為數組,則在scanf
和printf
調用中, 表達式 str
2將轉換為char *
。 如果將str
聲明為char *
,則已經是預期的類型。
現在,輸出(通常)是行緩沖的,這意味着除非有換行符或字符串的長度超過緩沖區長度,否則它不會顯示在控制台上。 您將要在打印語句中添加換行符:
printf( "%s\n", str );
或在標准輸出流上調用fflush
:
printf( "%s", str );
fflush( stdout );
確保顯示您的輸出。
sizeof
的操作數時,將發生此規則的例外。
_Alignof
或一元&
運算符,或者是用於初始化聲明中另一個數組的字符串文字。
"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()
上使用ncurses
和getch()
函數_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.