2010-09-30 7 views
0
#include<iostream> 
#include<fstream> 
#include<cstdlib> 
#include<string> 

using namespace std; 

**int main() 
{ 
    double write(); 
    double read(); 
    string choice; 

    while(1) 
    { 
     cout<<"Enter read to read a file and write to write a file.\n"; 
     cin>>choice; 
     if (choice == "read") 
     cout<< read(); 
     if (choice == "write") 
     cout<< write(); 
    } 
} 

double read() 
{  
    const int size = 60; 
    ifstream inFile; 
    char filename[size]; 
    cout<<"Enter the name of the file you want to read \n"; 
    cin.getline(filename, size); 
    inFile.open(filename);** 

    if(!inFile.is_open()) 
    { 
     cout<<"could not open "<<filename<<endl<<"program terminating"; 
     exit(EXIT_FAILURE); 
    } 

    double value; 
    double sum = 0.0; 
    int count = 0; 
    inFile >> value; 
    while(inFile.good()) 
    { 
     cout<<value<<"\n"; 
     ++count; 
     sum += value; 
     inFile >> value; 
    } 

    if (inFile.eof()) 
     cout<<"End of file reached. \n"; 
    else if (inFile.fail()) 
     cout<<"Input Terminated by data mismatch.\n"; 
    else 
     cout<<"input terminated for unknown reason"; 

    if (count == 0) 
     cout<<"no data processed"; 
    else 
    { 
     cout<<"Items read: "<<count<<endl; 
     cout<<"Sum: "<<sum<<endl; 
     cout<<"Average: "<<sum/count << endl; 
    } 
    inFile.close(); 
    return 0; 
} 

double write() 
{ 
    char type[81]; 
    char filename[81]; 

    cout<<"this program is more or less pointless, any text edtor on earth is better than this for writing"<<endl; 
    cout<<"files; However This is the first step in learning how to create my file tranfer program."<<endl; 
    cout<<"Enter the name of a file you want to create.\n"; 
    cin>>filename; 
    ofstream outFile; 
    outFile.open(filename); 

    outFile<<fixed; 
    outFile.precision(2); 
    outFile.setf(ios_base::showpoint); 
    while(!cin.fail()){ 
     cin.getline(type,81); 
     outFile<<type<<endl; 
    } 

    outFile.close(); 
} 

Le problème semble être que lorsque je tape "read" le programme fait ce qu'il est censé faire jusqu'à ce qu'il arrive à cin >> filename; à quel point je pense qu'il attribue la valeur de choix au nom de fichier parce que le programme saute à if (! inFile.is_open()) {après que je tape dans "read". (la fonction d'écriture de mon programme fonctionne très biencomment résoudre un conflit de données entre string et inFile.open

Quelqu'un pourrait me dire comment résoudre ce problème ou d'une autre manière pour que l'ordinateur décide de la météo à choisir parmi les fonctions lire ou écrire en fonction de la saisie de texte

Je suis nouveau en C++ donc j'apprécierais que la réponse soit simple , grâce

PS I, de m sur ubuntu si cela fait une différence

+0

Ce code inoffensif blesse les yeux. Je ne vais même pas le regarder. – sbi

+0

Il n'y a pas de fichier 'cin >>. Quel est également le problème car si vous l'aviez utilisé, vous n'auriez pas eu de problème (à moins que votre nom de fichier ne contienne un espace). –

Répondre

0

Il vous suffit de réconcilier votre utilisation de "cin >>" par rapport à "getline" lorsque vous voulez lire une chaîne. Leur comportement est légèrement différent.

Rappelez-vous que lorsque vous utilisez cin pour lire à partir de la console, chaque frappe que les touches de l'utilisateur va dans le tampon ciny compris le \ n pour le retour clé.

Ainsi, lorsque vos types d'utilisateur dans "lire" et coups reviennent pour entrer dans leur choix, le contenu de cin à ce moment-là sont:

lecture \ n

Ensuite, vous faites:

string choice; 
cin >> choice; 

Le problème est que l'opérateur >> est défini pour lire jusqu'à ce qu'il frappe les espaces, donc il va lire en "lecture", mais il restera \ n encore assis dans le tampon cin.

Ainsi, après votre déclaration cin >> choice, le contenu de cin sont:

\ n

Ensuite, vous allez faire ceci:

char filename[size]; 
cout<<"Enter the name of the file you want to read \n"; 
cin.getline(filename, size); 

Le problème ici est que l'opérateur >> est défini pour lire jusqu'à espace (comme \ n), mais getline est défini pour lire jusqu'à ce qu'il frappe un \ n et il lira tout sur la ligne jusqu'à ce qu'il voit un \ n et puis lire aussi dans le \ n et le jeter.

Eh bien votre problème est que quand vous arrivez à votre déclaration cin.getline(filename,size), il y a encore un caractère \ n assis dans le tampon cin et ainsi getline voit immédiatement le \ n et les rejets, le stockage de la chaîne vide dans filename.


Vous avez plusieurs choix ici.

Si vous faites le nom de fichier une chaîne et changé votre nom de fichier lu:

cin >> filename; 

Il fonctionnera correctement car l'opérateur >> ignore également le premier espace.

Vous pouvez également modifier votre lecture initiale de choice être comme celui-ci (en utilisant getline de l'en-tête de chaîne ici):

string choice; 
getline(cin,choice); 

Et cela fonctionnera parce que getline ne laissera pas le caractère parasite \ n assis dans le tampon cin.

Vous pouvez utiliser la fonction cin.ignore pour nettoyer le tampon cin. Vous ne voulez pas aveuglément utiliser ignore si vous ne savez pas ce que vous faites, mais nous savons dans ce cas que vous laissez un vagabondage sur cin, donc si vous voulez vous en débarrasser, vous pouvez le faire:

#include <limits> 

string choice; 
cin >> choice; 
cin.ignore(std::numeric_limits<int>::max(),'\n'); 

cette déclaration ignore efface essentiellement les données restantes dans cin en disant « jeter les caractères suivants INT_MAX ou tout jusques et y compris un \ n ».

Espérons que cela éclaircira ce qui se passe pour vous.

+0

Merci j'apprécie –

+0

J'apprécie vraiment quand les gens se mettent en quatre pour aider un étranger. –

0

Vous pouvez utiliser cin.ignore (INT_MAX).. à CLEA r le tampon d'entrée avant cin.getline (nom de fichier, taille);

+0

Vous masquez simplement l'erreur plutôt que de la corriger. –

0

Le problème est que vous ne lisez pas la « séquence de fin de vie » (AKA « \ n ») à partir du flux d'entrée:

cin>>choice; 

Ce lit un mot. Mais ne lit pas le caractère '\ n' de l'entrée.
Ainsi, la lecture suivante:

cin.getline(filename, size); 

lit Juste le « \ n » caractère que vous avez laissé sur le flux après la dernière lecture (plutôt que la ligne suivante que vous attendiez).

Lors de la lecture d'une entrée de l'utilisateur.
Je préfère toujours lire la ligne de l'entrée, puis la traiter en interne.

std::string command; 
std::getline(std::cin, command); // reads the whole line (but discards the '\n') 

if (command == "read") { /* Stuff */ } 

ensuite votre code pour obtenir le nom du fichier devrait fonctionner:

std::string filename; 
std::getline(std::cin, filename); 

std::ifstream(filename.c_str()); 

Tout fait.

Pendant que nous sommes ici: C'est astucieux car vous évitez le problème normal de la boucle sur un flux.
Mais il y a une meilleure solution (par mieux je veux dire plus compact):

inFile >> value; 
while(inFile.good()) 
{ 
    cout<<value<<"\n"; 
    ++count; 
    sum += value; 
    inFile >> value; 
} 

Essayez ceci:

while(inFile >> value) 
{ 
    cout<<value<<"\n"; 
    ++count; 
    sum += value; 
} 

Astuce 2: Je préfère utiliser std :: string sur un tampon de taille fixe char .

+0

Hey Merci à tous, j'ai utilisé char parce que c'est ce que mon livre a dit et je ne pouvais pas obtenir cin.getline pour l'entraînement. Je vais utiliser std :: string maintenant, merci –

0

Merci à tous; J'ai trouvé ma réponse en utilisant brent nash en mettant cette inclusion en haut du fichier source;

(#) comprennent

et en mettant ce code après mon cin >> choix;

cin.ignore (std :: numeric_limits :: max(), '\ n');

Je vais regarder dans les autres réponses si;

Questions connexes