[英]fprintf nested in for loop does not write the first element
我正在嘗試編寫一個csv表tablepath
,我需要在其中包括變量的名稱,這些變量位於文本文件filepath
。 我正在使用第一個函數read_par
從文件filepath
檢索名稱,並使用第二個函數store
來寫入表中。
創建的表在系統上缺少文本文件中第一個變量的名稱 。 read_par
函數可以正常工作並產生預期的輸出:一個包含變量名稱的字符串,我也將其包含在上下文中。
filepath
par1 0 1 0.5 par2 1 1 1 par3 0 1 1 par4 0 1 1 par5 0 1 1 par6 0 1 1
store
這是store
功能:
int store(int par_num, float sim_num, float **tab_param, char *filepath, char *tablepath){ int j; char *name = NULL; FILE* sim_table = NULL; sim_table = fopen(tablepath, "w"); // Start the first line in the table fprintf(sim_table,"simulation_number"); for(j=1; j < par_num+1; j++){ // If it is the last parameter -> create a new line if(j == par_num){ name = read_name(j, filepath); fprintf(sim_table,",%s\\n", name); }else{ /* If it is not the last parameter -> continue writing on * the same line */ name = read_name(j, filepath); fprintf(sim_table,",%s", name); } } fclose(sim_table); return 0; }
read_name
這是read_name
函數:
char *strtok(char *line, char *eof); char *read_name(int par_id, char *filepath){ char *par_name; int count = 0; FILE *file = fopen(filepath, "r"); if ( file != NULL ){ char line[256]; /* or other suitable maximum line size */ while (fgets(line, sizeof line, file) != NULL){ /* read a line */ if (count == (2*par_id)-2){ // strtok removes the \\n character from the string line strtok(line, "\\n"); par_name = line; fclose(file); } else{ count++; } } } else { printf("\\n\\n ERROR IN FUNCTION READ_PAR\\n\\nTEXT FILE IS EMPTY\\n\\n"); } return par_name; }
tablepath
我獲得的表如下所示:
┌─────────────────┬┬────┬────┬────┬────┬────┐
│simulation_number││par2│par3│par4│par5│par6│
└─────────────────┴┴────┴────┴────┴────┴────┘
缺少par1
名稱,但所有其他變量名稱均已成功打印。 我不知道問題出在哪里。 是在for循環條件下出現問題還是與par1
字符串本身有關?
感謝您對此的任何幫助。
問題是read_name
返回局部變量的地址( line
)。 函數返回時,該局部變量超出范圍(從技術上講,該變量不再存在)。 因此,使用返回的指針會導致未定義的行為 。
太清楚地看到了這個問題,這是read_name
的簡化版本,只顯示了相關行:
char *read_name(int par_id, char *filepath){
char *par_name;
char line[256]; // line is a local variable
while (fgets(line, sizeof line, file) != NULL){
par_name = line; // par_name now points to the local variable
}
}
return par_name; // returning the address of the local variable
}
在該問題下的注釋中指出,已對read_name
進行了測試,並發現其功能正常。 那么怎么可能是錯誤的呢? 這對於C語言中的未定義行為是最糟糕的事情。有時,即使在技術上不正確,該代碼在測試過程中也似乎可以正常工作。 從技術上講,我的意思是說它會在某個時候破裂。 例如,在store
函數中,如果在對read_name
的調用與對fprintf
調用之間添加了另一個函數調用,則很有可能name
會被破壞,並且無法正確打印。
在這種情況下,一個簡單的解決方案是使用static
關鍵字聲明line
:
static char line[256];
這樣, line
具有靜態的存儲持續時間,這意味着在read_name
返回后它將繼續存在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.