2017-05-14 3 views
-1

Ich übe derzeit Datei I/O in C. Ich erstellte ein Programm, wo ich eine Datei und extrahieren Sie Daten von ihm, und ich möchte eine Option, um die Datei zu ändern wird gelesen. Das Problem, das mir begegnet, ist, dass ich zum Beispiel zwei Dateien habe: sample1.txt und sample2.txt. Wenn ich sample1.txt als die erste Datei wählte, die gelesen werden soll, und dann wollte ich die Datei zu sample2.txt ändern, was schließlich passiert, ist, dass der Dateiname nicht zu sample2.txt ändert, sondern stattdessen immer was immer Dateiname die erste Datei hat.Ändern des aktuellen Dateinamens zu einem anderen mit fopen

Hier ist mein Code:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <strings.h> 
#include <assert.h> 
#include <time.h> 
#include <ctype.h> 
int main() 
{ 
char file_location[100]={0}; 
char new_location[100]={0}; 
    FILE* fPointer=NULL; 
    int choice; 

    printf("Enter the filename that you wish to open.\n"); 
    scanf("%[^\n]s",file_location);    // I enter sample1.txt// 
    printf("%s\n",file_location); 
    fPointer=fopen(file_location,"r"); // success,sample1.txt is currently being read.// 

if (fPointer==NULL) 
     { 
      printf("File error!,invalid file name! program will now exit.\n"); 
      exit(0); 
     } 
else 
     { 
      printf("Success!\n");  
     } 
    printf("Do you want to change the file being read\n); //Now I want to change the file,from sample1.txt to sample2.txt// 
    prinft("Enter 1 to change, 0 to exit the program\n); 
    do{ 
     scanf("%d",&choice);      
     printf("You entered %d\n",choice); 
     if(choice<0||choice>1) 
     { 
     printf("Error,please choose between 1 and 0\n"); 
     } 

    }while(choice!=1||choice!=0); 
     switch(choice)     // I enter 1,go to case1// 
    { 
     case 0: 
     printf("Exiting program now\n"); 
     exit(0); 
     break; 
     case 1: 
     fclose(fPointer); 
     printf("Enter the filename that you wish to open.\n");  
     scanf("%[^\n]s",new_location);   //scanf does not even prompt me to enter a string.// 
     printf("%s\n",new_location);  //nothing prints// 
     fPointer=fopen(new_location,"r"); // fpointer still points to sample1.txt// 
     break; 
    } 

return 0;   
} 

Könnte jemand mir erklären, warum versagt mein Code hält? Jede konstruktive Kritik, Hinweise zu File I/O wird geschätzt.

+0

Sie sind ein 'break' statment nach dem' Fall fehlen 1 'und der Standard ein –

+0

@JoaoTorres Danke, bearbeiten den Code. – Noobplox23

+2

@ Noobplox23 ** Einzug ** Ihr Code! – gsamaras

Antwort

2

Das grundlegende Problem ist, dass Ihr Code Zeilenumbrüche behandelt. Diese Methode der Eingabe zu erhalten wahrscheinlich nicht tut, was Sie denken, es tut:

scanf("%[^\n]s",new_location); 

Erstens gibt es keinen Grund für die s hier hinterher. Zweitens hinterlässt dies einen abschließenden Zeilenumbruch im Eingabestream. Dieser Zeilenumbruch wird ignoriert, wenn Sie scanf("%d",&choice); aufrufen, da der Konvertierungsbezeichner %d führende Leerzeichen überspringt. Aber dieser zweite Aufruf an scanf() hinterlässt auch ein Newline-Zeichen, und das wird von dem letzten Aufruf zu scanf() nicht ignoriert, da teilt, um Zeichen zu lesen, bis ein Zeilenumbruch auftritt.

Ein Fix ist, einfach die Scanset von Ihren scanf() Aussagen zu entfernen:

scanf("%s", new_location); 

Dies wird Leerzeichen ignorieren führt, so dass die Newline hinter vom vorherigen Aufruf scanf() ignoriert gelassen werden. Wenn Sie die neue Datei öffnen, verwenden Sie file_location anstelle von new_location.

Sie müssen Ihre do Schleifenbedingung ändern:

while(choice != 1 && choice != 0); 

, da Sie die Schleife nur wiederholen möchten, wenn der Benutzer eine Nummer eingibt, die beide nicht 0 und nicht 1

Wenn Wenn Sie Zeilen lesen möchten, die Leerzeichen enthalten, wird [^\n] manchmal verwendet. Eine bessere Alternative ist die Verwendung von fgets(). Diese Funktion behält den Zeilenumbruch bei, daher müssen Sie ihn aus den Dateinamen entfernen. Wenn Sie fgets() verwenden, um die Zeichenfolgen abzurufen, verwenden Sie am besten fgets(), um die numerische Eingabe zu erhalten, indem Sie die Benutzereingabe in einen Puffer lesen und sscanf() zum Analysieren verwenden. Dann Ihre Eingabe Code würde wie folgt aussehen:

/* Get first filename, and remove the newline */ 
printf("Enter the filename that you wish to open.\n"); 
fgets(file_location, sizeof file_location, stdin); 
file_location[strcspn(file_location, "\r\n")] = '\0'; // remove newline 

... 

/* Get numeric input; this keeps the newline, so it does not interfere 
* with the next call to `fgets()` */ 
char buffer[100]; 
fgets(buffer, sizeof buffer, stdin); 
sscanf(buffer, "%d", &choice); 

... 

/* Get the new filename, and remove the newline */ 
printf("Enter the filename that you wish to open.\n"); 
fgets(new_location, sizeof new_location, stdin); 
new_location[strcspn(new_location, "\r\n")] = '\0'; // remove newline 
+0

Danke! Ich werde deinen Vorschlag versuchen! – Noobplox23

+0

Ihr Vorschlag hat funktioniert! Vielen Dank! Ich habe gerade dieses Semester angefangen, C zu lernen, und File I/O war das letzte Thema, also wollte ich File I/O vor meinem Finale üben. – Noobplox23

+0

@ Noobplox23-- Ich habe einige Kommentare über die Verwendung von 'fgets()' für diese hinzugefügt, die eine bessere Lösung ist. Dies erlaubt die Eingabe von Strings, die Leerzeichen enthalten, was normalerweise für den Spezifizierer '[^ \ n]' verwendet wird, aber es ist einfacher zu arbeiten und flexibler. Wenn Sie darüber lesen möchten, dass nachfolgende Zeilenumbrüche aus Strings entfernt werden, [dies ist ein guter Link] (http://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input). –

Verwandte Themen