fopen מחזירה לי invalid argument

orsalmon

New member
fopen מחזירה לי invalid argument

שלום,
כתבתי קטע קוד (בשפת C) שמקבל מחרוזת מהמשתמש ומנסה לפתוח את הקובץ בשם של המחרוזת בעזרת fopen.
זה כתוב בתוך לולאה עד שהמחרוזת תואמת לקובץ קיים והוא מצליח לפתוח אותו.
אם אני מכניס בפעם הראשונה שם תקין וקיים הכל עובד פיקס.
הבעיה מתחילה כשאני מכניס בפעם הראשונה שם קובץ לא תקין - השגיאה שמודפסת לי היא No such file or directory (עד כאן סבבה) אבל כשאני מכניס לו בפעם השניה שם תקין הוא עדיין מדפיס לי שגיאה Invalid argument.
עשיתי לעצמי בדיקה שמדפיסה לי את המחרוזת שהמשתמש הכניס והבדיקה יוצאת לי תקינה. כלומר השם קובץ כן תקין וכן צריך לעבוד אך בכל זאת אני מקבל את השגיאה הזאת.

למישהו יש רעיון?
תודה מראש ושבוע טוב!!
 

BravoMan

Active member
תפרסם את הקוד.

תכתוב את הקטע הרלוונטי בין תגיות |הקוד| ו-|סקוד| או צרף אותו בקובץ טקסט פשוט.

אי אפשר לעזור לך בלי לראות את הקוד המדויק.
 

orsalmon

New member
קטע הקוד

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max_len 200

FILE* open_file(char *file_name,int *threshold) {
int i,dot_location;
char new_extension[12];
char *new_file_name;
FILE *original_image;
FILE *new_image;
start:
printf("Please enter *.bmp file direction, space and then\nThreshold integer number between 0-255\n");
printf("(For example: X.bmp 100)\n\n");
file_input:
for (i=0;i<max_len;i++) {
file_name=getchar();
if (file_name==' ') {
file_name='\0';
break;
}
}
dot_location=strlen(file_name)-4;
threshold_input:
scanf("%d",threshold);
if (file_name[dot_location]!='.' || file_name[dot_location+1]!='b' || file_name[dot_location+2]!='m' || file_name[dot_location+3]!='p') {
printf("\nBad input, please enter bmp file!\n\n");
goto file_input;
}
else if (*threshold>255 || *threshold<0) {
printf("\nThreshold value not allowed, please select an integer number between 0-255!\n\n");
for (i=0;i<max_len;i++)
if (file_name=='\0')
break;
else
printf("%c",file_name);
printf(" ");
goto threshold_input;
}

original_image=fopen(file_name,"rb");
if (original_image==NULL){
printf("\nFaild to open file! %s\n\n",strerror(errno));
goto start;
}
else
printf("\nSucceed to open file.. \n");
new_file_name=(char*)malloc((strlen(file_name)+8)*sizeof(char));
for (i=0;i<=dot_location;i++)
if (i!=dot_location)
new_file_name=file_name;
else
new_file_name='\0';

sprintf(new_extension,"_Out%d.bmp",*threshold);
strcat(new_file_name,new_extension);
strcat(new_file_name,"\0");
new_image=fopen(new_file_name,"wb");

free(new_file_name);
fclose(original_image);
return;
}

int main() {
char *file_name=(char*)malloc(sizeof(char)*max_len);
int *threshold=(int*)malloc(sizeof(int));
FILE *image=open_file(file_name,threshold);



return 0;
}
 

BravoMan

Active member
יש כמה דברים לא כ"כ טובים בקוד הזה,

כמו השימוש ב-goto שמאוד לא מומלץ (אם כי יש מקרים נדירים בהם הוא עדיף בצורה מאוד מצומצמת על פתרונות חלופיים), אבל אני אתייחס ספציפית לבעיית הקלט שלך:
אתה מתעלם מתווי "סוף שורה", התו שלחיצה על Enter מכניסה לקלט הסטנדרטי, ואחרי הפעם הראשונה בה אתה קולט את שם הקובץ תווים מיותרים אלה נכנסים למחרוזת שלך.

הם בלטי נראים בהדפסה (למעט אולי ירידת שורה שלא שמת לב עליה), אבל הם בהחלט יפריעו לפתיחת קבצים או בדיקות על מחרוזת שמסתמכות על מיקומים קבועים.
 

orsalmon

New member
תודה

אני אבדוק את זה.. תודה רבה!
ואתה ממליץ לעבוד עם לולאות while ותנאי יציאה במקום הgoto?

יום טוב
 

BravoMan

Active member
עברתי שוב על הקוד שלך, וזה מעלה עצלי כמה

שאלות:
1. האם מדובר בתרגיל, ואם כן האם הוא למטרה אישית, שעורי בית להגשה, או שזה חלק מעבודה של ממש?

הסיבה שאני שואל היא כדי לדעת מה הם המגבלות ו\או התנאים לפיהם צריך לכתוב את הקוד.

הסיבה שבאקדמיה אוסרים לחלוטין goto ובעולם האמתי כמעת לא משתמשים בו היא כי הוא יוצר "קוד ספגטי" - קוד שקופץ בצורה מסובכת ממקום למקום ולכן קשה לעקוב אחרי הזרימה שלו ולמצוא טעויות.

בדרך כלל צריך לחשוב טוב ולתכנן את זרימת הקוד הנכונה כדי לממש אותה מבצורה מסודרת וללא goto.

2. הקוד שלך כפי שהוא עכשיו תוקע את המשתמש בתוך הפונקציה open_file עד שהוא מצליח לפתוח קובץ חוקי בלי שום אפשרות לצאת או לבטל את הפעולה (למעט סגירת התוכנית בכוח).

האם זה אמור להיות ככה? יש דרישה כזו? אתה בטוחה שאתה רוצה לעשות את זה?

אם תספר קצת יותר על הפונקציה והדרישות והמגבלות (אם יש כאלה), אולי אפשר יהיה לעזור לך לסדר את הקוד בצורה קצת יותר יפה ונוחה לקריאה והבנה.
 

orsalmon

New member
כן זה תרגיל

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max_len 200

FILE *openFile(int *threshold) {
int i,dot_location,error_num,error_ext,error_read=0;
char new_extension[12];
char file_name[max_len];
char *new_file_name;
unsigned char c_data;
FILE *original_image;
FILE *new_image;


while (!error_read) {
error_ext=0;
error_num=0;
printf("Please enter *.bmp file path and Threshold integer number between 0-255\n(For exit press E)\n");
while (!error_ext) {
printf("FILE: ");
gets(file_name);
if (*file_name=='E')
exit(1);
dot_location=strlen(file_name)-4;
if (file_name[dot_location]!='.' || file_name[dot_location+1]!='b' || file_name[dot_location+2]!='m' || file_name[dot_location+3]!='p') {
printf("\nBad input, please enter bmp file!\n\n");
error_ext=0;
}
else
error_ext=1;
}

while (!error_num) {
printf("THRESHOLD: ");
scanf("%d",threshold);
if (*threshold>255 || *threshold<0) {
printf("\nThreshold value not allowed, please select an integer number between 0-255!\n\n");
printf("FILE: ");
for (i=0;i<max_len;i++)
if (file_name=='\0')
break;
else
printf("%c",file_name);
printf("\n");
error_num=0;
}
else
error_num=1;
}
original_image=fopen(file_name,"rb");
if (original_image==NULL){
printf("\nFaild to open file! %s\n\n",strerror(errno));
error_read=0;
}
else {
printf("\nSucceed to open file.. \n");
error_read=1;
}
}

new_file_name=(char*)malloc((strlen(file_name)+8)*sizeof(char));
for (i=0;i<=dot_location;i++)
if (i!=dot_location)
new_file_name=file_name;
else
new_file_name='\0';

sprintf(new_extension,"_Out%d.bmp",*threshold);
strcat(new_file_name,new_extension);
strcat(new_file_name,"\0");
new_image=fopen(new_file_name,"wb");

fseek(original_image,0L,SEEK_SET);
fseek(new_image,0L,SEEK_SET);

while (c_data=fgetc(original_image) != EOF)
fputc(c_data,new_image);

free(new_file_name);
fclose(original_image);

return new_image;
}

int main() {
int *threshold=(int*)malloc(sizeof(int));
FILE *new_image=openFile(threshold);




return 0;
}



שיפצתי קצת את הקוד. הורדתי את הgoto.. (תודה על ההערה)
הוספתי אפשרות יציאה..
התוכנית הכללית תעשה עיבוד תמונה על קובץ BMP.

יש לי בעיה קטנה עם התוכנית.. הקוד שכתבתי יוצר קובץ חדש ומעתיק אליו את הקובץ הישן. לדוגמא:
test.bmp עם ערך 123 שאני מכניס לו יוצר לי קובץ חדש test_Out123.bmp ומעתיק את המידע מהקובץ האורגינלי אליו.
הבעיה היא שלמרות שהfopen מחזירה לי הצלחה בפתיחת הקובץ - פעולת ההעתקה מכניסה לי מידע אך לא את המידע המקורי מהקובץ שנפתח. (כאילו הוא לא באמת הצליח לפתוח את הקובץ)
מקווה שהייתי ברור.. בכל מקרה תודה !!
 

orsalmon

New member
נפתרה הבעיה!

לא נתתי קדימות לאופרטור =
while (c_data=fgetc(original_image) != EOF)
fputc(c_data,new_image);


אני אוסיף סוגריים ויהיה בסדר..

תודה וחג שמח!
 
למעלה