[英]Input string to a char pointer member of an array of structure
我正在嘗試將字符串輸入到結構數組的char類型的指針成員。 程序在收到成員名稱為emp [0]的字符串后終止。 我的代碼:
#include<stdio.h>
struct Employee
{
char *name;
int salary;
};
int main()
{
struct Employee emp[3];
int i;
for(i=0;i<3;i++)
{
scanf("%s%d",emp[i].name,&emp[i].salary);
}
printf("\nOutput:");
for(i=0;i<3;i++)
{
printf("\n%s%d",emp[i].name,emp[i].salary);
}
return 0;
}
如果不使用數組,則以下用於某些變量emp
代碼可以正常工作:
scanf("%s%d",emp.name,&emp.salary);
有什么建議么? 提前致謝。
struct Employee
的name
字段是一個指針。 您永遠不會給該指針一個值,而是將其傳遞給scanf
,然后它嘗試取消引用它。 取消引用未初始化的指針會調用未定義的行為 。
而不是使用char *
作為name
,而是使它成為足以容納您期望的任何值的數組:
struct Employee
{
char name[50];
int salary;
};
您需要先初始化char
指針name
然后才能將其指向用戶輸入的String
。
#include<stdio.h>
struct Employee
{
char *name;
int salary;
};
int main()
{
struct Employee emp[3];
int i;
for(i=0;i<3;i++)
{
emp[i].name = (char*)malloc(3);
scanf("%s%d",emp[i].name,&emp[i].salary);
}
printf("\nOutput:");
for(i=0;i<3;i++)
{
printf("\n%s%d",emp[i].name,emp[i].salary);
}
return 0;
}
或者,您可以先分配一些name
然后再將其傳遞給scanf
。
emp[i].name = malloc(sizeof*emp[i].name*MAX_LEN);
if( !emp[i].name )
// error in malloc.
scanf
嘗試將讀取的字符寫到name
包含的地址中。 name
包含的地址不確定(某些垃圾值)。 訪問它需要未定義的行為。
它可以工作,但這是未定義的行為。 下次您運行相同的代碼時,可能會引發錯誤。
if
在malloc
之后是什么? 萬一malloc
無法提供所請求的內存,它將返回NULL
。 您正在檢查以確保已分配內存,否則將無法訪問它,因為它會調用未定義的行為。
是的,除了這一切,還有幾件事
malloc
的返回類型。 沒必要 free()
)。 scanf
返回值,以確保scanf
調用是否成功。 回復用戶評論:
如果在struct中有
name[4]
,則應編寫scanf("%3s",emp[i].name)
。 此3s
將scanf
讀取的字符限制為3
避免緩沖區溢出。 關鍵是,如果您輸入的字符數超過3個,則您只會讀取3個字符,其余字符將出現在輸入流中。
注意:問題以OR開頭,因為另一種方法是dbush回答的問題。 我不想重復。
通過對其他好的答案進行一點改進,我想介紹這個版本。
malloc()
返回,以確保在堆上分配某些所需的內存位置時成功或失敗。 如果失敗,則任何嘗試訪問該未分配內存的操作都會導致未定義行為。 malloc()
返回類型。 為什么不強制轉換malloc()的返回是危險的,請參閱第一個答案。 malloc()
時顯式#include <stdlib.h>
。 碼
#include <stdio.h>
#include <stdlib.h>
struct Employee
{
char *name;
int salary;
};
int main(){
struct Employee emp[3];
printf("Enter name, salary\n");
int i;
for(i=0;i<3;i++){
emp[i].name = malloc(40*sizeof(char));
if (emp[i].name != NULL){
scanf("%s %d", emp[i].name, &emp[i].salary);
}else{
///If this accur, try to access inside below for loop is UB
printf("Cant allocate Memory for name[%d]\n", i);
}
}
printf("\nOutput:\n");
for(i=0;i<3;i++)
{
printf("%s: %d\n", emp[i].name, emp[i].salary);
}
///Free allocated memory
printf("Free allocated memory\n");
for(i=0;i<3;i++)
{
free(emp[i].name);
}
return 0;
}
編譯並運行
gcc -Wall so.c -o so && ./so
[暗示]
您必須在姓名和工資整數之間插入一個空格或按Enter鍵。 盡管這可行,但是我建議為每個部分單獨分配scanf()
以獲得用戶輸入的姓名,薪金,然后按回車鍵,這是可讀的, 我認為 。
scanf("%s", emp[i].name);
scanf("%d", &emp[i].salary);
[ 注意事項 ]
嘗試避免使用scanf()
。 感謝@Jonathan Leffler提供了我從其中竊取的鏈接
我建議看看scanf()將新行char留在緩沖區中 ,當scanf()
掃描字符" %c"
留一個前導空格
[去做]
scanf()
行為中的"%c"
和"%d"
之間的相似性進行一些研究,刪除緩沖區。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.