# CSV-Datei mit C



## eyk107 (13. September 2012)

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


```
//
# 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) );
}
```


----------



## ComFreek (13. September 2012)

Wo ist jetzt dein genaues Problem/Fehler?



> Speicherung in einer (bevorzugt) xls Datei


Aber nicht im XLS-Format, oder? Wohl ever im CSV-Format.


----------



## sheel (13. September 2012)

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"? 

Gruß

PS: Nachträglich Willkommen bei tutorials.de


----------



## Alex_T (13. September 2012)

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.


----------



## eyk107 (14. September 2012)

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


----------



## sheel (14. September 2012)

@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 
[/spaß]


----------



## eyk107 (17. September 2012)

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


----------



## sheel (17. September 2012)

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.


----------



## eyk107 (17. September 2012)

tausend Dank nochmal was würde ich nur ohne dich machen ;-)


```
//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


----------



## sheel (17. September 2012)

sheel hat gesagt.:


> Wenn du einfach eine Zahl mit scanf einlesen willst, lass das \t weg.
> 
> Deine Zeileneinrückung ist seltsam.
> 
> ...


...Das goto überlass ich dir ;-]

```
//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) );
}
```



eyk107 hat gesagt.:


> - 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...



eyk107 hat gesagt.:


> - 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)?



eyk107 hat gesagt.:


> 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" 



eyk107 hat gesagt.:


> 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.


----------



## eyk107 (17. September 2012)

ja quasi ich gebe ein: 
Vorname, Name, kontonummer, kontostand-->danach kommt ein automatisches enter
Danach zweiter Datensatz
Vorname, Name, kontonummer, kontostand--> dieser wird aber nicht mehr mit ausgegeben...:-/
ändere ich scanf einfach nur in fgets**** der rest bleibt gleich?
Vllt ein bisschen viel verlangt aber hast du vllt ein beispiel oder einen link für die bearbeitung und die Löschung? Denn sind die wichtigsten Punkte erstmal fertig. Danke schonmal für den Aufwand wäre ohne die bisherige Hilfe nie so weit gekommen.
Mfg

Keiner eine Idee oder ein kleines Bsp. für die Bearbeitung?!
Mfg


----------



## sheel (19. September 2012)

sheel hat gesagt.:


> Wo, bei welcher Eingabe (wenn was eingegeben wird)?


Zeilennummer, und was genau eingegeben wird,
und wohin nichts ausgegeben wird...?
Da soll nämlich gar nichts ausgegeben werden.
Was erwartest du genau, was der Code tut?

@fgets: Das bekommt andere Parameter als scanf.
Findet man aber sehr leicht im Internet...

@Bearbeitung: Wie schon gesagt, du musst die komplette Datei einlesen.

Relativ einfach (aber nicht schön) wäre:
Eine zweite Datei zum Schreiben vorbereiten.
Eine Zeile von Datei1 einlesen, prüfen.
Wenn gelöscht werden soll, ncihts weiter tun.
Sonst in Datei2 reinschreiben.
Nachste Zeile von Datei1 einlesen, prüfen, wenn sie bleiben soll rausschreiben Richtung Datei2
usw...zeilenweise durch.
Am Schluss alle Dateien zu, Datei1 löschen und Datei2 umbenennen
(zum alten Dateinamen von Datei1).


----------

