CSV-Datei mit C

eyk107

Grünschnabel
Moin,
zuallererst erstmal sry falls ein Thema in der Richtung schon existiert aber ich konnte leider nichts finden.
Zu meinem Problem:
Ich muss für eine Belegarbeit mit C Kundendaten (Name, Vorname, Kontonummer, Kontostand) abfragen, die in einer txt oder xls Datei abspeichern, später wieder auslesen und bearbeiten können. Allerdings hapert es schon bei der Speicherung in einer (bevorzugt) xls Datei. Ich hoffe jemand von kann mir helfen. Übrigens ich programmiere mit Visual studio.
Danke schonmal.
Mfg Eric

Code:
//
# include "Stdafx.h"
# include "stdio.h"
# include "stdlib.h"
# include "windows.h"
# include "time.h"
# include "mmsystem.h"

#pragma comment (lib, "winmm.lib") //MCI

// Funktionsprototypen
void eingabe (void);
void zeit (void);
//void ausgabe (void); //
//void bearbeiten (void);	 //	
//void galgen (void);

int f, g, i, j;
char vorname[15];
char name [20];
char kontostand;
char kontonummer;


	FILE*datei; //Deklaration der Datei
	
// Hauptprogramm
void main(void)
{
	PlaySound (TEXT ("sound.wav"), NULL, SND_LOOP | SND_ASYNC) ; //Abspielen von Hintergrundmusik http://www.c-plusplus.de/forum/290724-full//
	
	menu1:
	system("color F0"); //Änderung der Hintergrundfarbe und Schrift
	menu2:					//Sprungpunkt für "goto Anweisung
	
	system ("cls");			//Clear screen

zeit();					//http://www.willemer.de/informatik/cpp/timelib.htm


	printf("\n\n\t --KUNDENDATENVERWALTUNGSPROGRAMM DKB-- \n"); 

	
printf("\n\n\t Druecken Sie die 1 um Kundendaten einzugeben: \n");
printf("\n\t Druecken Sie die 2 um Kundendaten einzusehen: \n");
printf("\n\t Druecken Sie die 3 um Kundendaten zu bearbeiten: \n");
printf("\n\t Druecken Sie die 4 um das Programm zu beenden: \n");
printf("\n\t Druecken Sie die 5 falls sie mit ihrer Arbeit fertig sind: \n");

printf("\n\t Druecken Sie die 10 um das Design des Programmes umzustellen: \n\t (eventuell ansprechender) \n");

 printf("\n\t Bitte treffen Sie eine Auswahl: \n");

scanf("\t %i", &i);

switch (i)			//Auswahlanweisung ähnlich zu if/ else (if i=1 und so weiter
{

case 1:
	{
	eingabe();
	goto menu2;
	}

case 2:
	{
	//ausgabe();
	goto menu2;
	}

case 3:
	{
	//bearbeiten();
	goto menu2;
	}

case 4:
	printf("\n\t Bis zum naechsten mal, angenehmen Tag noch! \n");
	break;

case 5:
	{
	//galgen();
	goto menu2;
	}

case 10:
	{
	system("color 0F"); //Änderung der Hintergrundfarbe und Schrift zum Standard
	//farbe();
	goto menu2;
	}

default:
	{
	system("color 0C");
	printf("\n\t Sie haben eine falsche Zahl eingegeben, bitte Wiederholen! \n");
	system("PAUSE");
	goto menu1;
	}
}

return; 
}


void eingabe(void)
{
   
		printf("\n\t KUNDENDATENEINGABE: \n\n");


 datei=fopen("Kundendaten.xls","w+");									//http://pronix.linuxdelta.de/C/standard_C/c_programmierung_19.shtml
   if(NULL == datei)													//http://de.wikibooks.org/wiki/C-Programmierung:_Dateien
      {
         printf("Konnte Datei \"test.txt\" nicht oeffnen!\n");
      }
 
printf("\n\t Wieviele Kundendaten moechten Sie eingeben?\n");
scanf("%i", &j);
for (f=0; f<j;f++)

{
printf("\n\t Bitte geben sie den Vornamen ein:\n");
scanf("%s",vorname);
fprintf (datei, " %s ",vorname);
 
printf("\n\t Bitte geben sie den Nachnamen ein:\n");
scanf("%s",name);
fprintf (datei, " %s ",name);
 
printf("\n\t Bitte geben sie die Kontonummer ein:\n");
scanf("%s",&kontonummer);
fprintf (datei, " %s ",&kontonummer);

printf("\n\t Bitte geben sie den aktuellen Kontostand ein:\n");
scanf("%s",&kontostand);
fprintf (datei, " %s ",&kontostand);
fclose (datei);

}
    return;
}

void zeit (void)
{

 time_t rawtime;
  struct tm * timeinfo;

  time ( &rawtime );
  timeinfo = localtime ( &rawtime );
  printf ( "\n\t\t\t\t %s ", asctime (timeinfo) );
}
 
Hi

paar Sachen, die mir generell auffallen:

Wenn du einfach eine Zahl mit scanf einlesen willst, lass das \t weg.

Deine Zeileneinrückung ist seltsam.

goto wird von vielen Programmierern als schlecht empfunden.
Das kann man auch mit Schleifen und ggf. einer weiteren Variablen,
ob das zwischen Marke 1 und 2 ausgeführt werden soll, lösen.

system PAUSE könnte man auch ohne externen Aufruf machen.
Ein printf und ein getchar, oÄ.

Globale Variablen sind auch nicht das Gelbe vom Ei,
vor allem wenn sie nur in einer einzigen Funktion
als Zählvariable für eine Schleife gebraucht werden.

scanf mit %s hat ein (gewolltes) Problem mit Leerzeichen.
Wenn man zB. beim Vornamen-eingeben zwei Vornamen hat und eingibt...
Die gets-Famile bzw. die Funktion fgets wäre sinnvoller.

Warum gibt es eine (auskommentierte) Funktion "galgen"? :D

Gruß

PS: Nachträglich Willkommen bei tutorials.de :)
 
Hallöle,

ich glaube in deiner Situation wäre es klüger mit einer Struktur zu arbeiten, sonst würde das über lange Sicht etwas ausarten, was die Position im File angeht (ich weiß ja nicht, was du damit noch so vor hast ;-)).
Weiterhin solltest du zum Debuggen mal die ganzen unnützen Sachen, wie z.B. die Designänderung über Bord werfen, damit man sich auf das Wichtigste konzentrieren kann.

Das eigentliche Problem wäre an dieser Stelle natürlich auch noch interessant.
 
Erstmal Danke für das Feedback. Also das Problem was ich zurzeit habe ist eigentlich nur das ich nicht weiß wie ich die eingegebenen Daten vom Programm in eine externe Datei schreiben lasse. Das Programm schreibt wenn dann nur den ersten eingegebenen Datensatz in das Programm. Hatte irgendwo gelesen das man das am besten mit .csv Dateien macht?!
P.S.:
Galgen ist das Galgen-Männchen-Spiel das muss ich nur noch reinkopieren das funktioniert soweit.
Die ganzen anderen Dinge habe ich nur mit drinne, weil mein Professor meinte, das sich jeder mit seiner Belegarbeit von allen anderen durch besondere DInge(bei mir Musik, Design usw.) absetzt.
Mfg
 
@Problem: Du machst in der for-Schleife (wo eingegeben und in die Datei geschrieben wird)
schon ein fclose. Nach dem ersten Datensatz ist die Datei damit zu, und beim Zweiten
gehts deswegen nicht mehr. Mach das fclose erst nach der gesamten Schleife.

@Am besten mit CSV: Was für welchen Anwendungsfall das Beste ist
kann man pauschal schwer sagen, aber da es sowieso nur ein Übungsprogramm ist...
CSV ist jedenfalls nichts Verkehrtes.

[spaß]
Sag deinem Professor, dass ein zeitgemäßes "Design" nicht in die Konsole passt :D
[/spaß]
 
Erstmal Danke für die schnelle Hilfe, hab es erstmal soweit hinbekommen.
Hab aber schonwieder ein neues Problem:
Ich würde gern die abgespeicherte Datei wieder auslesen. Habe auch etwas von einem Streamreader gehört, aber leider kein gutes Beispiel gefunden. Desweiteren sollen einzelne Daten in der Datei bearbeitet oder gelöscht werden.
Danke schonmal für eure Hilfe
mfg
 
Was mit gerade noch aufgefallen ist:
Eine CSV-Datei sollte , zwischen den einzelnen Werten (Vorname/Nachname...)
haben, sonst ist es ja kein CSV.

Zum Streamreader: Da bist du bei der falschen Programmiersprache.

Auslesen geht Ähnlich wie reinschreiben:
fopen mit r statt w+
fscanf statt fprintf, fgets statt fputs (falls verwendet)
fclose bleibt gleich

Zum Ändern/Löschen von Werten aus der Datei:
Hier, in diesem Fall, ist es nötig, alles auszulesen.
im Programm zwischenspeichern, dort ändern,
und dann wieder alles in die Datei zu schreiben
(auch die Sachen, die gleich geblieben sind).

Zeig vllt. mal den aktuelle Code, nach den bisherigen Änderungen.
 
tausend Dank nochmal was würde ich nur ohne dich machen ;-)

Code:
//BELEGARBEIT SS 2012 - Dominik Zentel, Marten Altkrüger, Eric Schmieder
//
//
# include "Stdafx.h"
# include "stdio.h"
# include "stdlib.h"
# include "windows.h"
# include "time.h"
# include "mmsystem.h"

#pragma comment (lib, "winmm.lib") //MCI

// Funktionsprototypen
void eingabe (void);
void zeit (void);
void ausgabe (void); //
//void bearbeiten (void);	 //	
//void galgen (void);

int  g, i;
char vorname[15];
char name [20];
char kontostand;
char kontonummer;


	FILE*datei; //Deklaration der Datei
	
// Hauptprogramm
void main(void)
{
	PlaySound (TEXT ("sound.wav"), NULL, SND_LOOP | SND_ASYNC) ; //Abspielen von Hintergrundmusik http://www.c-plusplus.de/forum/290724-full//
	
	menu1:
	system("color F0"); //Änderung der Hintergrundfarbe und Schrift
	menu2:					//Sprungpunkt für "goto Anweisung
	
	system ("cls");			//Clear screen

zeit();					//http://www.willemer.de/informatik/cpp/timelib.htm


	printf("\n\n\t --KUNDENDATENVERWALTUNGSPROGRAMM DKB-- \n"); 

	
printf("\n\n\t Druecken Sie die 1 um Kundendaten einzugeben: \n");
printf("\n\t Druecken Sie die 2 um Kundendaten einzusehen: \n");
printf("\n\t Druecken Sie die 3 um Kundendaten zu bearbeiten: \n");
printf("\n\t Druecken Sie die 4 um das Programm zu beenden: \n");
printf("\n\t Druecken Sie die 5 falls sie mit ihrer Arbeit fertig sind: \n");

printf("\n\t Druecken Sie die 10 um das Design des Programmes umzustellen: \n\t (eventuell ansprechender) \n");

 printf("\n\t Bitte treffen Sie eine Auswahl: \n");

scanf("\t %i", &i);

switch (i)			//Auswahlanweisung ähnlich zu if/ else (if i=1 und so weiter
{

case 1:
	{
	eingabe();
	goto menu2;
	}

case 2:
	{
	ausgabe();
	system("PAUSE");
	goto menu2;
	}

case 3:
	{
	//bearbeiten();
	goto menu2;
	}

case 4:
	printf("\n\t Bis zum naechsten mal, angenehmen Tag noch! \n");
	system("PAUSE"); //auch mit getchar() probiert aber der text wird nur kurz angezeigt?!
	break;

case 5:
	{
	//galgen();
	goto menu2;
	}

case 10:
	{
	system("color 0F"); //Änderung der Hintergrundfarbe und Schrift zum Standard
	//farbe();
	goto menu2;
	}

default:
	{
	system("color 0C");
	printf("\n\t Sie haben eine falsche Zahl eingegeben, bitte Wiederholen! \n");
	system("PAUSE");
	goto menu1;
	}
}

return; 
}


void eingabe(void)
{
   int f,i,j;

		printf("\n\t KUNDENDATENEINGABE: \n\n");


 datei=fopen("Kundendaten.csv","w+");									//http://pronix.linuxdelta.de/C/standard_C/c_programmierung_19.shtml
   if(NULL == datei)													//http://de.wikibooks.org/wiki/C-Programmierung:_Dateien
      {
         printf("Konnte Datei \"Kundendaten.csv\" nicht oeffnen!\n");
      }
 
printf("\n\t Wieviele Kundendaten moechten Sie eingeben?\n");
scanf("%i", &j);
for (f=1; f<=j;f++)

{
fprintf (datei, " ,%i ",f);
printf("\n\t Bitte geben sie den Vornamen ein:\n");
scanf("%s",vorname);
fprintf (datei, " ,%s ",vorname);
 
printf("\n\t Bitte geben sie den Nachnamen ein:\n");
scanf("%s",name);
fprintf (datei, " ,%s ",name);
 
printf("\n\t Bitte geben sie die Kontonummer ein:\n");
scanf("%s",&kontonummer);
fprintf (datei, " ,%s ",&kontonummer);

printf("\n\t Bitte geben sie den aktuellen Kontostand ein:\n");
scanf("%s",&kontostand);
fprintf (datei, " ,%s ",&kontostand);
fprintf (datei, "\n");
}

fclose (datei);
    return;
}

void ausgabe (void)
{
		printf("\n\t KUNDENDATENAUSGABE: \n\n");


 datei=fopen("Kundendaten.csv","r");									//http://pronix.linuxdelta.de/C/standard_C/c_programmierung_19.shtml
   if(NULL == datei)													//http://de.wikibooks.org/wiki/C-Programmierung:_Dateien
      {
         printf("Konnte Datei \"Kundendaten.csv\" nicht oeffnen!\n");
      }

fscanf (datei, " ,%s ",vorname);
printf ("%s",vorname);

fscanf (datei, " ,%s ",name);
printf ("%s",name); 

fscanf (datei, " ,%s ",&kontonummer);
printf ("%s",&kontonummer);

fscanf (datei, " ,%s ",&kontostand);
printf("%s",&kontostand);

 
fclose (datei);
    return;  
}



void zeit (void)
{

 time_t rawtime;
  struct tm * timeinfo;

  time ( &rawtime );
  timeinfo = localtime ( &rawtime );
  printf ( "\n\t\t\t\t %s ", asctime (timeinfo) );
}

EIn Paar Sachen sind mir noch aufgefallen:
- getchar statt system(Pause) lässt den Text unter Punkt 4 trotzdem nur kurz anzeigen!?
- Nach der ersten eingegebenen Zeile gibt das Programm leider nicht mehr aus (höchstwahrscheinlich aufgrund des "Enters" nach der ersten Eingabe nach "Kontostand"

Muss leider noch dazusagen, das wir sowas nie wirklich behandelt haben. Daher tue ich mich auch ein bisschen schwer. Und ein halbwegs gutes Beispiel konnte ich auch nicht finden. Es gibt ja anscheinend auch hier 1000 Wege die nach Rom führen ;-) Es gibt vllt bessere Wege Dateien anzulegen aber ich würde gern bei meiner Variante bleiben, da ich diese Art und Weise halbwegs gut verstanden habe.
Mfg
 
Wenn du einfach eine Zahl mit scanf einlesen willst, lass das \t weg.

Deine Zeileneinrückung ist seltsam.

goto wird von vielen Programmierern als schlecht empfunden.
Das kann man auch mit Schleifen und ggf. einer weiteren Variablen,
ob das zwischen Marke 1 und 2 ausgeführt werden soll, lösen.
...Das goto überlass ich dir ;-]
C++:
//BELEGARBEIT SS 2012 - Dominik Zentel, Marten Altkrüger, Eric Schmieder
//
//
# include "Stdafx.h"
# include <stdio.h>
# include <stdlib.h>
# include <windows.h>
# include <time.h>
# include <mmsystem.h>

#pragma comment (lib, "winmm.lib") //MCI

// Funktionsprototypen
void eingabe (void);
void zeit (void);
void ausgabe (void); //
//void bearbeiten (void);    // 
//void galgen (void);

int  g, i;
char vorname[15];
char name [20];
char kontostand;
char kontonummer;


FILE *datei; //Deklaration der Datei

// Hauptprogramm
void main(void)
{
	PlaySound (TEXT ("sound.wav"), NULL, SND_LOOP | SND_ASYNC) ; //Abspielen von Hintergrundmusik http://www.c-plusplus.de/forum/290724-full//

	menu1:
	system("color F0"); //Änderung der Hintergrundfarbe und Schrift
	menu2:                  //Sprungpunkt für "goto Anweisung

	system ("cls");         //Clear screen

	zeit();                 //http://www.willemer.de/informatik/cpp/timelib.htm


	printf("\n\n\t --KUNDENDATENVERWALTUNGSPROGRAMM DKB-- \n"); 


	printf("\n\n\t Druecken Sie die 1 um Kundendaten einzugeben: \n");
	printf("\n\t Druecken Sie die 2 um Kundendaten einzusehen: \n");
	printf("\n\t Druecken Sie die 3 um Kundendaten zu bearbeiten: \n");
	printf("\n\t Druecken Sie die 4 um das Programm zu beenden: \n");
	printf("\n\t Druecken Sie die 5 falls sie mit ihrer Arbeit fertig sind: \n");

	printf("\n\t Druecken Sie die 10 um das Design des Programmes umzustellen: \n\t (eventuell ansprechender) \n");

	printf("\n\t Bitte treffen Sie eine Auswahl: \n");

	scanf("%i", &i);

	switch (i)          //Auswahlanweisung ähnlich zu if/ else (if i=1 und so weiter
	{
		case 1:
		{
			eingabe();
			goto menu2;
		}

		case 2:
		{
			ausgabe();
			system("PAUSE");
			goto menu2;
		}

		case 3:
		{
			//bearbeiten();
			goto menu2;
		}

		case 4:
		{
			printf("\n\t Bis zum naechsten mal, angenehmen Tag noch! \n");
			system("PAUSE"); //auch mit getchar() probiert aber der text wird nur kurz angezeigt?!
			break;
		}

		case 5:
		{
			//galgen();
			goto menu2;
		}

		case 10:
		{
			system("color 0F"); //Änderung der Hintergrundfarbe und Schrift zum Standard
			//farbe();
			goto menu2;
		}

		default:
		{
			system("color 0C");
			printf("\n\t Sie haben eine falsche Zahl eingegeben, bitte Wiederholen! \n");
			system("PAUSE");
			goto menu1;
		}
	}

	return; 
}


void eingabe(void)
{
	int f, i, j;

	printf("\n\t KUNDENDATENEINGABE: \n\n");


	datei=fopen("Kundendaten.csv","w+");                                   //http://pronix.linuxdelta.de/C/standard_C/c_programmierung_19.shtml
	if(NULL == datei)                                                    //http://de.wikibooks.org/wiki/C-Programmierung:_Dateien
	{
		printf("Konnte Datei \"Kundendaten.csv\" nicht oeffnen!\n");
	}

	printf("\n\t Wieviele Kundendaten moechten Sie eingeben?\n");
	scanf("%i", &j);
	for (f = 1; f <= j;f++)
	{
		fprintf (datei, " ,%i ",f);
		printf("\n\t Bitte geben sie den Vornamen ein:\n");
		scanf("%s", vorname);
		fprintf (datei, " ,%s ",vorname);

		printf("\n\t Bitte geben sie den Nachnamen ein:\n");
		scanf("%s", name);
		fprintf (datei, " ,%s ",name);

		printf("\n\t Bitte geben sie die Kontonummer ein:\n");
		scanf("%s", &kontonummer);
		fprintf (datei, " ,%s ",&kontonummer);

		printf("\n\t Bitte geben sie den aktuellen Kontostand ein:\n");
		scanf("%s", &kontostand);
		fprintf (datei, " ,%s ",&kontostand);
		fprintf (datei, "\n");
	}

	fclose (datei);
	return;
}

void ausgabe (void)
{
	printf("\n\t KUNDENDATENAUSGABE: \n\n");


	datei=fopen("Kundendaten.csv","r"); //http://pronix.linuxdelta.de/C/standard_C/c_programmierung_19.shtml
	if(NULL == datei)                   //http://de.wikibooks.org/wiki/C-Programmierung:_Dateien
	{
		printf("Konnte Datei \"Kundendaten.csv\" nicht oeffnen!\n");
	}

	fscanf (datei, " ,%s ",vorname);
	printf ("%s",vorname);

	fscanf (datei, " ,%s ",name);
	printf ("%s",name); 

	fscanf (datei, " ,%s ",&kontonummer);
	printf ("%s",&kontonummer);

	fscanf (datei, " ,%s ",&kontostand);
	printf("%s",&kontostand);


	fclose (datei);
	return;  
}



void zeit (void)
{
	time_t rawtime;
	struct tm * timeinfo;

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	printf ( "\n\t\t\t\t %s ", asctime (timeinfo) );
}

- getchar statt system(Pause) lässt den Text unter Punkt 4 trotzdem nur kurz anzeigen!?
Aja, das ist noch ein Problem mit scanf.
Wenns mit system-pause funktioniert, bleib dabei.
Trotzdem, aus den oben genannten Gründen wäre fgets besser.
Es gibt ja auch Leute mit einem zweiten Vornamen...mit Leerzeichen...

- Nach der ersten eingegebenen Zeile gibt das Programm leider nicht mehr aus (höchstwahrscheinlich aufgrund des "Enters" nach der ersten Eingabe nach "Kontostand"
Wo, bei welcher Eingabe (wenn was eingegeben wird)?

Muss leider noch dazusagen, das wir sowas nie wirklich behandelt haben. Daher tue ich mich auch ein bisschen schwer. Und ein halbwegs gutes Beispiel konnte ich auch nicht finden. Es gibt ja anscheinend auch hier 1000 Wege die nach Rom führen ;-)
Jo...allein über scanf könnte man viele Seiten schreiben...
"Das Monster scanf - Probleme und Fallen einer vermeintlich einfachen Funktion" :D

Es gibt vllt bessere Wege Dateien anzulegen aber ich würde gern bei meiner Variante bleiben, da ich diese Art und Weise halbwegs gut verstanden habe.
Am Datei-anlegen ist nichts Schlechtes.
 
Zurück