i was trying to make a JSONParser in C and it partly works.
The only problem is that the Terminal shows everything twice.
For Example, instead of showing just "Name", it gives out "Name" Name.
Thats the Code (some of the variables and comments are in German):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct person {
int PID;
int alter;
int freunde[20];
char* vname;
char* nname;
}person;
int MAX_PERSONS = 10;
char* substr(const char *source, int m, int n)
{
int len = abs(n - m);
char *destination = (char*)malloc(sizeof(char) * (len + 1));
for (int i = m; i < n && (*(source + i) != '\0'); i++)
{
*destination = *(source + i);
destination++;
}
*destination = '\0';
return destination - len;
}
const char* readNext(FILE* fp)
{
const char* string = malloc(1024); /*Speicherreservierung*/
const char* retvalue;
if (fscanf(fp, "%s", string) == 1) /*solange es erfolgreich ist, fragt es ab, bis ein leerzeichen kommt*/
{
while(strcmp(string,":") == 0 ) /*doppelpunkt wird ignoriert*/
{
fscanf(fp, "%s", string);
}
printf("\n %s", string); /*gibt einen String aus*/
if(strncmp(string,"\"",1) == 0)
{
if(strcmp(substr(string, strlen(string)-1, 1 ),",") == 0) /*kontrolliert, ob ein Beistrich vorkommt*/
{
retvalue = substr(string, 1, strlen(string)-2); /*kommt ein Beistrich vor, so werden zwei vom ende abgezogen, sonst nur einer*/
}
else
{
retvalue = substr(string, 1, strlen(string)-1);
} /*nun sind die Anfuehrungszeichen weg*/
printf("\n %s", retvalue);
return retvalue;
}
else
{
printf("\n %s", string);
return string;
}
}
return NULL;
}
int readInit(FILE* fp) /*hiermit wird der Anfang der Datei gelesen*/
{
const char* readValue= readNext(fp);
}
return strcmp(readValue,"{"); /*string wird mit { verglichen*/
void readPid(FILE* fp, person* pp)
{
const char* a = readNext(fp); /*file pointer auf die naechste stelle*/
if(strstr(a, "pid")> 0) /*kontrolle, ob wir schon an der Stelle PID sind*/
{
a = readNext(fp);
}
(*pp).PID = atoi(a); /*https://www.proggen.org/doku.php?id=c:lib:stdlib:atoi: die Funktion atoi wird in diesem Fall die anfuehrungszeichen los und speichert die ID ab*/
}
void readName(FILE* fp, person* pp)
{
readNext(fp); /*pointer wird weitergesetzt*/
if(readInit(fp) != 0) /*ueberpruefung ob es richtig startet*/
{
printf("\n Falsche Syntax - File does not start with {") ;
}
const char* a = readNext(fp); /*filepopinter geht weiter*/
if(strstr(a, "vname") > 0) /*Richtigkeits ueberpruefung*/
{
(*pp).vname = readNext(fp); /*pointer geht weiter auf namen und speichert es ins struct*/
}
a = readNext(fp);
if(strstr(a, "nname") > 0) /*ueberpruefung ob es der nachname ist*/
{
(*pp).nname = readNext(fp); /*file pointer geht auf nachnamen und speichert*/
}
}
int readAge(FILE* fp,person* pp )
{
readNext; /*ueberspringen des },*/
const char* a = readNext(fp);
if(strstr(a, "alter")> 0) /*ueberpruefung ob wir an der stelle alter sind*/
{
a = readNext(fp); /*filepointer geht weiter zum alter*/
}
(*pp).PID = atoi(a);
return 0;
}
int readFreunde(FILE* fp,person* pp )
{
readNext; /*ueberspringen des ,*/
const char* a = readNext(fp);
if(strstr(a, "freunde")> 0) /*ueberpruefung ob wir an der stelle freunde sind*/
{
a = readNext(fp); /*filepointer geht weiter zu den freunden ids*/
}
(*pp).PID = atoi(a);
return 0;}
/*
int * readFriends(FILE* fp)
{
int retvalue[] = {0,1};
return retvalue;
}
*/
person* readPerson(FILE* myFileRef) /*file pointer wird as parameter mitgegeben*/
{
person* myPers = (person*) malloc(1 * sizeof(person)); /*speicher wird reserviert fuer die auszulesenden daten der person*/
if(readInit(myFileRef) != 0) /*es wird ueberprueft ob das file richtig beginnt*/
{
printf("\n Falsche Syntax - File does not start with {") ;
}
readPid(myFileRef, myPers); /*auslagerung der einzelnen daten in funktionen*/
readName(myFileRef, myPers);
readAge(myFileRef, myPers);
readFreunde(myFileRef, myPers);
return myPers;
}
void optionone()
{
FILE* myJson = NULL; /*Initialisierung des File Pointers*/
printf("Option 1 gewaehlt \n");
myJson = fopen("personen.json", "r"); /*file wird mit "r" geoeffnet, das heißt die Datei wird nur gelesen und nicht geaendert*/
person* myPersLib[MAX_PERSONS] ; /*struct wird initialisiert*/
int i = 0;
if(myJson != NULL) /*ueberpruefung ob das file leer ist*/
{
person* myPers = readPerson(myJson); /*ablesefunktion ausgelagert*/
while(&myPers != NULL && i < MAX_PERSONS) /*schleife um alle strings durchzugehen, insofern das file nicht leer ist und man die maximale anzahl nicht ueberschreitet*/
{
myPersLib[i] = myPers;
i++;
myPers = readPerson(myJson);
}
fclose(myJson); /*datei wird geschlossen*/
}
else
{
printf("Datei nicht vorhanden"); /*ist die Datei nicht in dem gleichen Ordner, so entsteht eine Fehlermeldung "Datei nicht vorhanden" */
}
}
void optiontwo()
{
char str[15];
int b = 0;
person mypers;
printf("\n Option 2 gewaehlt\n");
printf("\nID eingeben: "); /*Abfrage der ID*/
scanf("%d", &b);
b = mypers.PID;
printf("\nVorname eingeben:"); /*Abfrage des Vornamens*/
scanf("%s", str);
*str = mypers.vname; /*string pointer weil es eine "modifiable value" sein muss*/
printf("\n Nachname eingeben:"); /*Abfrage des Nachnamens*/
scanf("%s", str);
*str = mypers.nname;
printf("\n Alter eingeben: "); /*Abfrage des Alters*/
scanf("%d", &b);
b = mypers.alter;
printf("\n ID eingeben: "); /*Abfrage der ID (friends)*/
scanf("%d", &b);
b = mypers.freunde;
}
int main()
{
int a = 0;
printf("1. Einlesen \t 2. Eingeben und als File speichern");
printf("\n Option waehlen: "); /*mit der switch case wird die Option abgefragt, einlesen oder eingeben*/
scanf("%d", &a);
switch (a)
{
case 1: /*erste option der switch case*/
optionone();
break;
case 2: /*zweite option der switch case*/
optiontwo();
break;
default:
printf("Ungueltige Option"); /*wird etwas anderes als 1 oder zwei bei der Optionsauswahl ausgewaehlt, so wird es unterbrochen und es entsteht eine Fehlermeldung*/
break;
}
return 0;
}
And after the terminal compiles the File, thats what it spits out:
1. Einlesen 2. Eingeben und als File speichern
Option waehlen: 1
Option 1 gewaehlt
{
{
"pid"
pid
"1138",
1138"
"name"
name
{
{
"vname"
vname
"Leia",
Leia"
"nname"
nname
"Organa"
Organa
},
},
"alter"
alter
"21",
21"
Falsche Syntax - File does not start with {
"freunde"
freunde
[
[
{"pid"
{"pid"
Falsche Syntax - File does not start with {
"0987"}
0987"
,
,
{"pid"
{"pid"
"7778"}
7778"
]
]
Falsche Syntax - File does not start with {
},
},
{
{
"pid"
pid
Falsche Syntax - File does not start with {
"7778",
7778"
"name"
name
{
{
"vname"
vname
"Luke",
Luke"
Falsche Syntax - File does not start with {
"nname"
nname
"Skywalker"
Skywalker
},
},
Falsche Syntax - File does not start with {
"alter"
alter
"21",
21"
"freunde"
freunde
[
[
{"pid"
{"pid"
Falsche Syntax - File does not start with {
"0987"}
0987"
,
,
{"pid"
{"pid"
Falsche Syntax - File does not start with {
"1138"}
1138"
]
]
},
},
{
{
"pid"
pid
Falsche Syntax - File does not start with {
"0987",
0987"
"name"
name
{
{
"vname"
vname
"Din",
Din"
"nname"
nname
"Djarin"
Djarin
},
},
"alter"
alter
"35",
35"
Falsche Syntax - File does not start with {
"freunde"
freunde
[
[
{"pid"
{"pid"
Falsche Syntax - File does not start with {
"7778"}
7778"
,
,
{"pid"
{"pid"
"1138"}
1138"
]
]
Falsche Syntax - File does not start with {
}
}
Related
This question already has answers here:
Why can we not declare a variable after a switch case colon without using curly braces?
(3 answers)
Closed last month.
I got the following C code here and following error messages and just don't know how to solve it:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma warning (disable: 4996)
#define MAX_ROWS 20
#define MAX_COLS 30
typedef struct {
char data[MAX_ROWS][MAX_COLS];
int rows;
int cols;
} Matrix;
char neighbor_count(Matrix* m, int row, int col) {
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
if (i < 0 || i >= m->rows) {
continue;
}
for (int j = col - 1; j <= col + 1; j++) {
if (j < 0 || j >= m->cols) {
continue;
}
if (m->data[i][j] == '*' && (i != row || j != col)) {
count++;
}
}
}
return count;
}
void check_cell(Matrix* m, int row, int col) {
char neighbors_count = neighbor_count(m, row, col);
char current_cell = m->data[row][col];
if (neighbors_count < 2) { //Die Zelle stirbt an Vereinsamung
m->data[row][col] = ' ';
}
else if (neighbors_count > 3 && current_cell == '*') { //Die Zelle stirbt an Übervölkerung
m->data[row][col] = ' ';
}
else if (neighbors_count == 3 && current_cell == ' ') { //Aus der toten Zelle wird eine neue lebende Zelle
m->data[row][col] = '*';
}
else if (neighbors_count == 2 || neighbors_count == 3) { //Die Zelle lebt weiter
m->data[row][col] = '*';
}
}
void load_from_file(Matrix* m, const char* filename) {
FILE* f = fopen(filename, "r");
if (f == NULL) {
printf("File not found\n");
exit(-1);
}
int row_idx = 0;
char ch;
while ((ch = fgetc(f)) != EOF && row_idx < MAX_ROWS) {
if (ch == '\n') {
row_idx++;
continue;
}
m->data[row_idx][m->cols] = ch;
m->cols++;
}
m->rows = row_idx;
fclose(f);
}
void randomize(Matrix* m, int percent) {
m->rows = MAX_ROWS;
m->cols = MAX_COLS;
int cells = (m->rows * m->cols) * (percent / 100.0f);
srand(time(NULL));
while (cells > 0) {
int row = rand() % m->rows;
int col = rand() % m->cols;
if (m->data[row][col] == ' ') {
m->data[row][col] = '*';
cells--;
}
}
}
void print_matrix(Matrix* m) {
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
printf("%c", m->data[i][j]);
}
printf("\n");
}
printf("\n");
}
void step(Matrix* m) {
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
check_cell(&m_tmp, i, j);
}
}
*m = m_tmp;
}
int main() {
Matrix m;
// Menü zur Auswahl des Startzustands
printf("1. Aus Datei laden\n");
printf("2. Zufallszustand generieren\n");
int selection;
scanf("%d", &selection);
switch (selection) {
case 1: // Aus Datei laden
char filename[20];
printf("Bitte Dateinamen angeben: ");
scanf("%s", filename);
load_from_file(&m, filename);
break;
case 2: // Zufallszustand generieren
int percent;
printf("Prozentualer Anteil an lebenden Zellen: ");
scanf("%d", &percent);
randomize(&m, percent);
break;
default:
printf("Ungültige Eingabe\n");
return 0;
}
// Menü zur Auswahl der Animation
printf("1. Schrittweise Animation\n");
printf("2. Fließende Animation\n");
scanf("%d", &selection);
switch (selection) {
case 1: // Schrittweise Animation
while (1) {
print_matrix(&m);
step(&m);
getchar();
}
break;
case 2: // Fließende Animation
while (1) {
print_matrix(&m);
step(&m);
usleep(200000);;
}
break;
default:
printf("Ungültige Eingabe\n");
break;
}
return 0;
}
and this error messages
E1072 A declaration cannot have a label. CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\CGoL Beleg Prog\Quelle.c 119
E1072 A declaration cannot have a label.. CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\CGoL Beleg Prog\Quelle.c 125
LNK2019 Reference to unresolved external symbol "usleep" in function "main". CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\CGoL Beleg Prog\Quelle.obj 1
LNK1120 1 unresolved external CGoL Beleg Prog C:\Users\d-enk\OneDrive\Desktop\UNI MEDIENINFORMATIK\Programmierung\Vorlesung 1\CGoL Beleg Prog\x64\Debug\CGoL Beleg Prog.exe 1
"A declaration cannot have a label" means that you cannot declare variables in the middle of a switch/case. You can solve this by adding a local compound statement:
case 1: // Aus Datei laden
{
char filename[20]; // this one was causing the problem
printf("Bitte Dateinamen angeben: ");
scanf("%s", filename);
load_from_file(&m, filename);
break;
}
Same thing with int percent;.
"Reference to unresolved external symbol "usleep"" means that the compiler can't find usleep. Most likely because it is obsolete in Windows. See this c++, usleep() is obsolete, workarounds for Windows/MingW?.
I have created a Discord bot for my Minecraft server. The bot connects to my Discord server. The problem is that it does not respond. (See code).
#Override
public void onMessageReceived(MessageReceivedEvent event) {
if(event.getAuthor().isBot() || event.isWebhookMessage()) return;
TextChannel textChannel = event.getGuild().getTextChannelById("850164284402040872");
String[] args = event.getMessage().getContentRaw().split(" ");
if(args[0].equalsIgnoreCase("!link")) {
if(event.getChannel().equals(textChannel)) {
if (Objects.requireNonNull(event.getMember()).getRoles().stream().filter(role -> role.getId().equals("834086832408625152")).findAny().orElse(null) != null) {
textChannel.sendMessage(":x: **|** Error! " + event.getAuthor().getAsMention() + ", du bist bereits verifiziert!").queue();
return;
}
if (uuidIdMap.containsValue(event.getAuthor().getId())) {
textChannel.sendMessage(":x: **|** Error! " + event.getAuthor().getAsMention() + ", du hast bereits einen Code generiert!").queue();
return;
}
if (args.length != 2) {
textChannel.sendMessage(":x: **|** Error! Du musst einen Spieler angeben!").queue();
return;
}
Player target = Bukkit.getPlayer(args[1]);
if (target == null) {
textChannel.sendMessage(":x: **|** Error! Der Spieler konnte nicht gefunden werden").queue();
return;
}
int n = 20;
uuidCodeMap.put(target.getUniqueId(), randomCode(n));
uuidIdMap.put(target.getUniqueId(), event.getAuthor().getId());
for(String code : uuidCodeMap.values()) {
event.getAuthor().openPrivateChannel().complete().sendMessage("Hey! Du hast erfolgreich einen Code generiert!\n" + "Benutze diesen Befehl: ``/discord " + code + "``").queue();
}
textChannel.sendMessage(":white_check_mark: **|** Ein Code wurde generiert. Schaue bitte nach.").queue();
}
}
}
I have the following the following structures to define an Binary Search Tree:
typedef struct Equipo {
char nombre[50];
char marcaMoto[30];
int puntuaciones;
struct Piloto pilotos[18];
struct nodo* izquierdo;
struct nodo* derecho;
} Equipo;
typedef Equipo Arbol;
the search in the tree will be performed by the string nombre, a char [50]. For create tree and insert data I use the functions:
Equipo* CrearEquipo(Equipo* e) {
Equipo* n = (Equipo *) malloc(sizeof(Equipo));
strncpy(n->nombre, e->nombre, 50);
strncpy(n->marcaMoto, e->marcaMoto, 30);
n->puntuaciones = 0;
n->derecho = n->izquierdo = NULL;
return n;
}
void InsertarEquipo(Equipo** arbol, Equipo* e) {
if (*arbol == NULL) {
Equipo* n = CrearEquipo(e);
*arbol = n;
} else {
int comparado = strncmp(e->nombre, (*arbol)->nombre, 50);
if (comparado > 0) {
InsertarEquipo(&(*arbol)->izquierdo, e);
} else {
InsertarEquipo(&(*arbol)->derecho, e);
}
}
}
And in main i use this functions to create test elements:
Equipo* equipo = (Equipo *) malloc(sizeof(Equipo));
strcpy(equipo->nombre, "C");
strcpy(equipo->marcaMoto, "B");
Arbol *arbol = CrearEquipo(equipo);
strcpy(equipo->nombre, "B");
strcpy(equipo->marcaMoto, "B");
InsertarEquipo(&arbol, equipo);
strcpy(equipo->nombre, "A");
strcpy(equipo->marcaMoto, "B");
InsertarEquipo(&arbol, equipo);
strcpy(equipo->nombre, "E");
strcpy(equipo->marcaMoto, "B");
InsertarEquipo(&arbol, equipo);
Later, I create the recursive function for comprobate if exists in the tree:
int ExisteEquipo(Equipo* arbol, char nombre[]) {
int comparado = strncmp(arbol->nombre, nombre, 50);
if (!arbol) {
return 0;
} else if (comparado > 0) {
printf("Menor ");
return ExisteEquipo(arbol->izquierdo, nombre);
} else if (comparado < 0) {
printf("Mayor ");
return ExisteEquipo(arbol->derecho, nombre);
} else {
printf("Igual ");
return 1;
}
}
(The printf's are for test). When I call the exists function with:
void DeterminarExistencia(Equipo* arbol, char nombre[50]) {
if (ExisteEquipo(arbol, nombre)) {
printf("El nodo %s existe. \n", nombre);
} else {
printf("El nodo %s no existe. \n", nombre);
}
}
DeterminarExistencia(arbol, "E");
DeterminarExistencia(arbol, "C");
DeterminarExistencia(arbol, "H");
DeterminarExistencia(arbol, "B");
but I always get the error: Violación de segmento (core dumped) [Núcleo vaciado a un archivo]
I think the problem is here:
int comparado = strncmp(arbol->nombre, nombre, 50);
You are asking if arbol is null after operating with it with the line above, so if it is null you are accessing a wrong memory address and that is causing the error.
Put it like this:
if (!arbol) {
return 0;
int comparado = strncmp(arbol->nombre, nombre, 50);
Spanish:
Básicamente cambia el orden de lo que te he dicho arriba y deberia funcionar.
I have a text file with 2 lines in it:
Voicu;Catalin;1234;2.32
Diana;Cadar;2345;1.01
I'm trying to make my program search in .txt file the ID (1234 or 2345) and match it to the name. Below is the code I've tried to make, but it won't find the ID in .txt after I write it in first scanf, the first thing that appears is the "else" line.
void alegereStudent(struct student *stud)
{
FILE *scStudenti = fopen("studenti.txt", "a");
char *error;
int i=0,n;
if(scStudenti==NULL)
{
error = strerror(errno);
printf("Fisierul nu poate fi creat: \n %s", error);
}
printf("\nIntroduceti Numele: ");
scanf("%39s", stud->numeStudent);
printf("Introduceti Prenumele: ");
scanf("%39s", stud->prenumeStudent);
printf("Introduceti ID-ul studentului: ");
scanf("%d", &stud->idStudent);
printf("Introduceti Media de admitere: ");
scanf("%f", &stud->medieAdmitere);
fprintf(scStudenti,"<%s>;", stud->numeStudent);
fprintf(scStudenti,"<%s>;", stud->prenumeStudent);
fprintf(scStudenti,"<%d>;", stud->idStudent);
fprintf(scStudenti,"<%.2f>\n", stud->medieAdmitere);
fclose(scStudenti);
}
//
void optiunea_2()
{
printf("\n1.Despre studenti.\n");
printf("2.Despre profesori.\n");
printf("3.Revenire la meniu principal.\n");
printf("\nAlegeti o optiune: ");
scanf("%d",&alegere_opt2);
switch(alegere_opt2)
{
case 1: while(&stud!=NULL)
{
FILE *scStudenti = fopen("studenti.txt", "r");
char *error;
int cautareID;
if(scStudenti==NULL)
{
error = strerror(errno);
printf("Fisierul nu poate fi creat: \n %s", error);
}
printf("\nIntroduceti ID-ul studentului: ");
scanf("%d", &cautareID);
fscanf(scStudenti,"%d",&stud->idStudent);
if(cautareID==&stud->idStudent)
{
printf("Numele Studentului este %s %s",&stud->numeStudent, &stud->prenumeStudent);
}
else
printf("\nAcest ID nu exista!\n");
optiunea_2();
}break;
fprintf(scStudenti,"<%s>;", stud->numeStudent);
fprintf(scStudenti,"<%s>;", stud->prenumeStudent);
fprintf(scStudenti,"<%d>;", stud->idStudent);
fprintf(scStudenti,"<%.2f>\n", stud->medieAdmitere);
fclose(scStudenti);
This makes formatting much more difficult. The output file will contain:
<first>;<last>;<1234>;<0.5>
You want to start with a new file and simplify the output to write:
first;last;1234;0.5
Don't always put & in front of integer. Just use:
if(cautareID == stud->idStudent)
{
...
}
Example:
const char *filename = "studenti.txt";
void alegereStudent()
{
struct student stud;
FILE *scStudenti = fopen(filename, "a");
if(scStudenti == NULL)
{
printf("error\n");
return;
}
printf("\nIntroduceti Numele: ");
scanf("%39s", stud.numeStudent);
printf("Introduceti Prenumele: ");
scanf("%39s", stud.prenumeStudent);
printf("Introduceti ID-ul studentului: ");
scanf("%d", &stud.idStudent);
printf("Introduceti Media de admitere: ");
scanf("%f", &stud.medieAdmitere);
fprintf(scStudenti, "%s;", stud.numeStudent);
fprintf(scStudenti, "%s;", stud.prenumeStudent);
fprintf(scStudenti, "%d;", stud.idStudent);
fprintf(scStudenti, "%.2f\n", stud.medieAdmitere);
fclose(scStudenti);
}
void find_by_id(int id)
{
FILE *fin = fopen(filename, "r");
if(!fin)
return;
int count = 0;
struct student stud;
while(fscanf(fin, "%39[^;];%39[^;];%d;%f\n",
stud.numeStudent, stud.prenumeStudent, &stud.idStudent, &stud.medieAdmitere) == 4)
{
if(id == stud.idStudent)
{
printf("found %s %s\n", stud.numeStudent, stud.prenumeStudent);
}
count++;
}
if(count == 0)
printf("failed to read any record. Start with a new file.\n");
}
int main(void)
{
alegereStudent();
find_by_id(1234);
return 0;
}
If <> characters are added, then read according to that format, you then have to remove the extra <> characters from the string.
void alegereStudent()
{
struct student stud;
...
fprintf(scStudenti, "<%s>;", stud.numeStudent);
fprintf(scStudenti, "<%s>;", stud.prenumeStudent);
fprintf(scStudenti, "<%d>;", stud.idStudent);
fprintf(scStudenti, "<%.2f>\n", stud.medieAdmitere);
fclose(scStudenti);
}
void find_by_id(int id)
{
...
struct student stud;
while(fscanf(fin, "%39[^;];%39[^;];<%d>;<%f>\n",
stud.numeStudent, stud.prenumeStudent, &stud.idStudent, &stud.medieAdmitere) == 4)
{
if(id == stud.idStudent)
{
char *p;
size_t i;
//remove the extra <> characters
p = stud.numeStudent;
if (strlen(p) > 1)
{
for(i = 1; i < strlen(p) - 1; i++)
p[i - 1] = p[i];
p[i - 1] = 0;
}
//remove the extra <> characters
p = stud.prenumeStudent;
if (strlen(p) > 1)
{
for(i = 1; i < strlen(p) - 1; i++)
p[i - 1] = p[i];
p[i - 1] = 0;
}
printf("found %s %s\n", stud.numeStudent, stud.prenumeStudent);
}
count++;
}
if(count == 0)
printf("failed to read any record. Start with a new file.\n");
}
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char const *filename = "test.txt";
FILE *input = fopen(filename, "r");
if (!input) {
fprintf(stderr, "Couldn't open \"%s\" for reading!\n\n", filename);
return EXIT_FAILURE;
}
char name[101];
char surname[101];
int id;
double value;
while (fscanf(input, "%100[^;];%100[^;];%d;%lf%*[\n]", name, surname, &id, &value) == 4) {
if (id == 2345) {
printf("Found \"%s %s\" by id %d\n\n", name, surname, id);
break;
}
}
}
As in the headline.
Simple exercise, trying to learn structures and other essential c functionality.
Here is a structure containing a char[] and a number, I try to save its values in a file and read them back.
I read through a lot of topics concerning Seg.fault by fopen(), but can't find my mistake!
Someone here who knows why fopen() does crash in this instance?
Any suggestions and criticism on the matter is welcome!
The function where the Segfault happens is load():
void load(struct Telephon *structure, int *counter)
{
char filename[255];
char puffer[255], puffercpy[255];
int i, c, newline_count;
size_t strlaen;
FILE *datei=NULL;
char *token=NULL;
printf("\033[0;35mWelche Datei oeffnen?\033[0m\n");
scanf("%s", filename);
//emptystdin();
//strlaen=strlen(filename);
//printf("%d", strlaen);
//filename[strlaen+1] = '\0';
//printf("\n%s", filename);
datei = fopen(filename, "r");
if(datei==NULL)
{
printf("\033[0;31mKonnte Datei %s nicht oeffnen.\033[0m\n", filename);
}
else
{
while ( (c=fgetc(datei)) != EOF ) //count lines of file
{
if ( c == '\n' )
{
newline_count++;
}
}
for(i=0; i<=newline_count; i++) //get values in between ";"
{
fgets(puffer, 254, datei);
strcpy(puffercpy, puffer);
token = strtok(puffercpy, ";");
*counter = atoi(token);
token = strtok(NULL, ";");
strcpy(structure[i].name, token);
token = strtok(NULL, ";");
structure[i].nummer = atoi(token);
}
fclose(datei);
}
return;
}
The whole code, main is at the end:
telephonListen.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#define MAX 100
struct Telephon
{
char name[210];
unsigned int nummer;
}TELE[MAX];
char* gotTime(char *timestrg)
{
time_t now;
now = time(NULL);
strftime (timestrg, 19, "%d.%m.%Y, %H:%M", localtime (&now));
return timestrg;
}
void printT(struct Telephon *structarray, int addcount)
{ int i;
if(addcount==0)
{
printf("\033[0;31mEs sind noch keine Eintraege vorhanden!\033[0m\n");
return;
}
else
{
for(i=0; i<addcount; i++)
{
printf("\nEintrag Nr.%d\n%s:\t%d\n",i+1, structarray[i].name, structarray[i].nummer);
}
return;
}
}
void eingabe(int num, struct Telephon *structarray)
{
size_t inputlen;
int check;
if(num>MAX)
{
printf("\033[0;31mMaximale Anzahl von Eintraegen erreicht!\033[0m\n");
return;
}
else
{
printf("\n\033[0;35mNamen eingeben:\t\033[0m");
//fgets(structarray[num].name, MAX, stdin);
fgets(structarray[num].name, 209, stdin);
inputlen=strlen(structarray[num].name);
structarray[num].name[inputlen-1]='\0';
printf("\n\033[0;35mNummer eingeben:\t \033[0m");
do
{
check = scanf("%10u", &structarray[num].nummer);
}while( getchar()!='\n');
fflush(stdin);
if(check==1)
{
printf("Ihr Kontakt wurde angelegt!\n%s:\t%u\n", structarray[num].name ,structarray[num].nummer);
}
else
{
printf("Fehler bei der Eingabe. Kontakt wurde nicht angelegt!");
return;
}
return;
}
}
void writeFile(struct Telephon *structure, char *zeitf, int counter)
{
char filename[255];
int i;
FILE *datei;
if(counter>0)
{
printf("\033[0;35mIn welche Datei soll das Telephonbuch geschrieben werden?\n(Achtung: Vorhandene Dateien werden ueberschrieben!)\t\033[0m\n");
scanf("%s", filename);
getchar();
datei = fopen(filename, "w");
if(NULL == datei)
{
printf("\033[0;31mKonnte Datei %s nicht öffnen.\033[0m\n", filename);
}
fprintf(datei, "Telephonverzeichnis vom %s\nNAME\t\t|NUMMER\n\n", zeitf);
for(i=0; i<counter; i++)
{
fprintf(datei, "%s\t\t|%d\n", structure[i].name, structure[i].nummer);
}
printf("\033[0;32mDatei gespeichert.\033[0m\n");
fclose(datei);
}
else
{
printf("\033[0;31mEs sind noch keine Eintraege vorhanden!\033[0m\n");
return;
}
return;
}
void change(struct Telephon *structure, int count)
{
int eintragnum;
if (count == 0)
{
printf("\033[0;31mEs sind noch keine Eintraege vorhanden!\033[0m\n");
return;
}
else
{
printT(structure, count);
printf("\033[0;31mWelcher Eintrag soll geaendert werden?\033[0m\n");
do
{
scanf("%d", &eintragnum);
}while(getchar()!='\n');
if(eintragnum<1||eintragnum>count)
{
printf("\033[0;31mBitte die Nummer [zwischen %d und %d]\n des zu aendernden Eintrags eingeben!\033[0m\n", 1, count);
}
else
{
eingabe(eintragnum-1, structure);
}
}
return;
}
void emptystdin()
{
int c;
while( ((c = getchar()) != EOF) && (c != '\n') );
}
void searchContact(struct Telephon *structure, int count)
{
char searchC;
int inputlen;
int i=0;
int countcompare;
if (count == 0)
{
printf("\033[0;31mEs sind noch keine Eintraege vorhanden!\033[0m\n");
return;
}
else
{
printf("Anfangsbuchstabe:\t");
scanf("%c", &searchC);
emptystdin();
for(i=0; i<count; i++)
{
if(structure[i].name[0]==searchC)
{
printf("Eintrag gefunden:\n");
printf("Nr. %d\nName:\t%s\nNummer:\t%u\n", i+1, structure[i].name, structure[i].nummer);
}
}
return;
}
}
void save(struct Telephon *structure, int counter)
{
char filename[255];
int i;
FILE *datei;
if(counter>0)
{
printf("\033[0;35mUnter welchem Dateinamen speichern?\n(Achtung: Vorhandene Dateien werden ueberschrieben!)\t\033[0m\n");
scanf("%s", filename);
emptystdin();
datei = fopen(filename, "w");
if(NULL == datei)
{
printf("\033[0;31mKonnte Datei %s nicht anlegen.\033[0m\n", filename);
}
for(i=0; i<counter; i++)
{
fprintf(datei, "%d;%s;%d\n", i+1, structure[i].name, structure[i].nummer);
}
printf("\033[0;32mDatei gespeichert.\033[0m\n");
fclose(datei);
}
else
{
printf("\033[0;31mEs sind noch keine Eintraege vorhanden!\033[0m\n");
}
return;
}
void load(struct Telephon *structure, int *counter)
{
char filename[255];
char puffer[255], puffercpy[255];
int i, c, newline_count;
size_t strlaen;
FILE *datei=NULL;
char *token=NULL;
printf("\033[0;35mWelche Datei oeffnen?\033[0m\n");
scanf("%s", filename);
//emptystdin();
//strlaen=strlen(filename);
//printf("%d", strlaen);
//filename[strlaen+1] = '\0';
//printf("\n%s", filename);
datei = fopen(filename, "r");
if(datei==NULL)
{
printf("\033[0;31mKonnte Datei %s nicht oeffnen.\033[0m\n", filename);
}
else
{
while ( (c=fgetc(datei)) != EOF ) //Zeilen in Datei zählen
{
if ( c == '\n' )
{
newline_count++;
}
}
for(i=0; i<=newline_count; i++) //CVS parsen/auslesen
{
fgets(puffer, 254, datei);
strcpy(puffercpy, puffer);
token = strtok(puffercpy, ";");
*counter = atoi(token);
token = strtok(NULL, ";");
strcpy(structure[i].name, token);
token = strtok(NULL, ";");
structure[i].nummer = atoi(token);
}
fclose(datei);
}
return;
}
int main(void)
{
int auswahl;
int count = 0;
char zeit[20];
char buffer[2];
struct Telephon *structptr; //malloc(MAX*(sizeof(TELE)));
structptr = TELE;
gotTime(zeit);
system("clear");
printf("Telephonkontaktverwaltung\t%s\n", zeit);
do
{
printf("\033[30;47m1: Kontakt hinzufuegen\t2: Kontakte anzeigen\n3: Kontakt aendern\t4: Als Datei speichern\n5. Kontakt suchen\n6. Als CVS sichern\t7. Aus CVS laden\n8. Beenden\nEine der Ziffern eingeben, mit Enter bestaetigen\033[0m\n");
/*
scanf("%d", &auswahl);
scanf("%c", &buffer);
fgets(buffer, 2, stdin);
if(isdigit(buffer[1]))
{
auswahl=atoi(buffer);
}
else
{
printf("Eine der Nummern eingeben um Aktion auszufuehren!\n");
}
do
{
scanf("%d", &auswahl);
}while(getchar()!='\n');
fgets(buffer, 2, stdin);
sscanf(buffer, "%d", &auswahl);
*/
scanf("%d", &auswahl);
emptystdin();
switch (auswahl)
{
case 1 : eingabe(count++, structptr);
break;
case 2 : printT(structptr, count);
break;
case 3 : change(structptr, count);
break;
case 4 : writeFile(structptr, gotTime(zeit), count);
break;
case 5 : searchContact(structptr, count);
break;
case 6 : save(structptr, count);
break;
case 7 : load(structptr, &count);
break;
case 8 : printf("ENDE\n");
break;
default : printf("Eine der Nummern eingeben um Aktion auszufuehren!\n");
break;
}
}while(auswahl!=8);
return EXIT_SUCCESS;
}
Use rewind().
Between the while() and for() loops, the file need to start at the beginning again.
while ( (c=fgetc(datei)) != EOF ) //count lines of file
{ ...}
rewind(datei);
for(i=0; i<=newline_count; i++) //get values in between ";"
{ ...}
Strongly suggest avoid using scanf() and fgets(,,stdin). Recommend one. Preferable fgets().
You likely want scanf(" %c", instead of scanf("%c",. (Add space).
Minor Idea:
Not that English is the be-all end-all language, but OP may want to consider something like
// Bold Red "Could not create file" EOL
const char *Err_FileCreation_format = "\033[0;31mKonnte Datei %s nicht anlegen.\033[0m\n"
printf(Err_FileCreation_format, filename);
// or
#define Err_FileCreation_fmt1 "\033[0;31mKonnte Datei "
#define Err_FileCreation_fmt2 " nicht anlegen.\033[0m\n"
printf(Err_FileCreation_fmt1 "%s" Err_FileCreation_fmt2, filename);
Assuming undefined behaviour hadn't been invoked prior to a call to fopen() the only way to make it crash is to pass it a non-initialised or non-0-terminated character array as file name or mode.
So to avoid this properly initialise all variables used to hold a file name and/or mode by declaring it like:
char filename[256] = "";
To avoid allowing scanf() to read in more then filenamecan hold do like this:
scanf("%255s", filename);
Update:
This code
while ( (c=fgetc(datei)) != EOF ) //count lines of file
{
if ( c == '\n' )
{
newline_count++;
}
}
reads until the end of the file.
So this code
for(i=0; i<=newline_count; i++) //get values in between ";"
{
fgets(puffer, 254, datei);
strcpy(puffercpy, puffer);
token = strtok(puffercpy, ";");
*counter = atoi(token);
token = strtok(NULL, ";");
strcpy(structure[i].name, token);
token = strtok(NULL, ";");
structure[i].nummer = atoi(token);
}
would not be able to read anything, as eof had already been reached.
However the code does not test whether fgets() might have failed but happily starts parsing what it didn't read and ... crashes during atoi()ing a token pointing to NULL.