Read a CSV file in C - c

I have to read a file in the console in C, the file is a CSV file. My code is the following :
printf("Ajouter un site internet \n");
printf("------------------------------------------\n");
FILE * curseur = fopen("listess.csv", "a");
SITES * pSites = calloc(100000, sizeof(SITES));
int i = 0;
int iSites = 0;
int champSites = 0;
char temp[1000];
if (curseur != NULL) {
char c = fgetc(curseur);
while (c != EOF) {
printf("%s", (pSites + iSites)->url);
if (c != '\n' && c != ';') {
temp[i] = c;
i++;
}
else if (c == ';') {
temp[i] = '\0';
if (champSites == 0) {
strcpy((pSites + iSites)->Commune, temp);
champSites++;
i = 0;
}
else if (champSites == 1) {
strcpy((pSites + iSites)->Insee, temp);
champSites++;
i = 0;
}
else if (champSites == 2) {
strcpy((pSites + iSites)->url, temp);
champSites++;
i = 0;
}
else if (champSites == 3) {
strcpy((pSites + iSites)->Population, temp);
champSites++;
i = 0;
}
else if (champSites == 4) {
strcpy((pSites + iSites)->https, temp);
champSites++;
i = 0;
}
else if (champSites == 5) {
strcpy((pSites + iSites)->Serveur, temp);
champSites++;
i = 0;
}
else if (champSites == 6) {
strcpy((pSites + iSites)->Version, temp);
champSites++;
i = 0;
}
else if (champSites == 7) {
strcpy((pSites + iSites)->Application, temp);
champSites++;
i = 0;
}
else if (champSites == 8) {
strcpy((pSites + iSites)->VersionApplication, temp);
champSites++;
i = 0;
}
else if (champSites == 9) {
strcpy((pSites + iSites)->Langage, temp);
champSites++;
i = 0;
}
else if (champSites == 10) {
strcpy((pSites + iSites)->VersionLangage, temp);
champSites++;
i = 0;
}
else if (champSites == 11) {
strcpy((pSites + iSites)->Latitude, temp);
champSites++;
i = 0;
}
else if (champSites == 12) {
strcpy((pSites + iSites)->Longitude, temp);
champSites++;
i = 0;
}
}
else {
iSites++;
}
c = fgetc(curseur);
}
system("pause");
fclose(curseur);
}
But I do have any result in the console except the two first lines.
The file is composed of 13 columns that I declared in a .h file.
The 5 first lines of the csv:
Commune;Code Insee;url;Population;https;Serveur;Version du serveur;Application;Version de l'application;Langage;Version du langage;Latitude;Longitude
Argentat;19010;argentat.fr;3042;non;SiteW;2;Inconnue;Inconnue;php;5.3.29;45.100801186828598;1.934640270901890
Canenx-et-Réaut;40064;mairie-info.com;175;non;SiteW;2;Inconnue;Inconnue;php;5.3.29;43.999060134922502;-0.464769980981436
Chaussan;69051;chaussan.fr;972;non;SiteW;2;Inconnue;Inconnue;Inconnue;Inconnue;45.637283899086498;4.634069843807340
Étrez;1154;etrez.fr;803;non;SiteW;2;Inconnue;Inconnue;Inconnue;Inconnue;46.338283686023097;5.192873875680920
Gray ;70279;ville-gray.fr;6016;non;SiteW;2;Inconnue;Inconnue;php;5.2.10;47.432262030641297;5.610925314619960

Your code is overly complicated. Throw it away and base your new code on this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
// declare and initialize your pSites stuff here
....
//
if (curseur == NULL)
{
printf("Can't open file\n");
return 1;
}
int linenumber = 1;
char buffer[1000];
while (fgets(buffer, sizeof buffer, curseur))
{
char *token = strtok(buffer, ";");
printf("Line %d\n", linenumber++);
int column = 0;
while (token != NULL)
{
printf("%2d %s\n", column, token);
switch (column)
{
case 0:
strcpy((pSites + iSites)->Commune, token);
break;
case 1:
strcpy((pSites + iSites)->Insee, token);
break;
case 2:
.... etc.
}
token = strtok(NULL, ";");
column++;
}
iSites++;
}
fclose(curseur);
}
BTW: instead of writing
(pSites + iSites)->Commune
you should write the more readable variant:
pSites[iSites]->Commune

This:
if (champSites == 0) {
strcpy((pSites + iSites)->Commune, temp);
champSites++;
i = 0;
}
else if (champSites == 0) {
strcpy((pSites + iSites)->Insee, temp);
champSites++;
i = 0;
}
makes no sense, note that both conditions are else if(champSites == 0) which will clearly mean that most of the code is dead (won't ever execute).
Should perhaps be if 0 ... else if 1 ... else if 2 and so on.

Related

Connect four game, if statement

Here is code for my connect four game for exam. There are seven columns, if a number above 7 is entered it should say "Move not allowed", but if 0 is entered it should save the game.
When I enter 0 it says "Move not allowed". There is a code to save the game when 0 is entered but it says "Move not allowed" and doesn't go there. Can someone help?
#include <stdio.h>
#include <string.h>
typedef struct gameState{
int id;
char board[6][7];
int numberOfMoves;
char player1Name[20];
char player2Name[20];
}GameState;
void ShowMenu() {
printf("\n\n\n1. New Game \n");
printf("2. Load Game \n");
printf("3. Exit \n\n");
printf("Choose: ");
}
void ReadPlayerNames(char player1Name[20], char player2Name[20]) {
printf("\nName of first player:");
scanf("%s", player1Name);
printf("\nName of second player:");
scanf("%s", player2Name);
}
void PrintBoard(char board[6][7])
{
char header[] = " 1 2 3 4 5 6 7 ";
char border[] = "|---|---|---|---|---|---|---|";
printf("%s\n", header);
printf("%s\n", border);
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
printf("| %c ", board[i][j]);
}
printf("|\n");
printf("%s\n", border);
}
}
void ClearBoard(char board[6][7]) {
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++) {
board[i][j] = ' ';
}
}
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckDiagonals(char board[6][7], int i, int j, int goUpRight){
int connectedO = 0;
int connectedX = 0;
while(i >= 0){
if (board[i][j] != ' '){
if (board[i][j] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (goUpRight = 0){
board[i][j] = 'Y'; //checking if x won, putting Y on places of x
board[i + 1][j + 1] = 'Y';
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (goUpRight = 0){
board[i][j] = 'Y';
board[i + 1][j + 1] = 'Y'; //checking if o won, putting Y on places of o
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
i--;
if (goUpRight == 1){
j++;
}else{
j--;
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckRowsOrCols(char board[6][7], int rows){
int connectedO = 0;
int connectedX = 0;
int brI = 6;
int brJ = 7;
if (rows == 0){
brI = 7;
brJ = 6;
}
for (int i = 0; i < brI; i++){
for (int j = 0; j < brJ; j++) {
int pI = i, pJ = j;
if (rows == 0){
pI = j;
pJ = i;
}
if (board[pI][pJ] != ' '){
if (board[pI][pJ] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckForWinner(char board[6][7]) {
int rezultat = CheckRowsOrCols(board, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckRowsOrCols(board, 0);
if (rezultat != 0){
return rezultat;
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 0, 1);
if (rezultat != 0){
return rezultat;
}
}
for (int j = 0; j < 7; j++){
rezultat = CheckDiagonals(board, 5, j, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckDiagonals(board, 5, j, 0);
if (rezultat != 0){
return rezultat;
}
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 6, 0);
if (rezultat != 0){
return rezultat;
}
}
return 0;
}
void SaveGame(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]){
printf("\n\n\nEnter ID for your game: ");
int id;
scanf("%d", &id);
GameState state;
state.id = id;
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++){
state.board[i][j] = board[i][j];
}
}
state.numberOfMoves = movesPlayed;
strcpy(state.player1Name, player1Name);
strcpy(state.player2Name, player2Name);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "ab");
if (filePointer == NULL){
printf("\nGames not found!");
return;
}
fwrite(&state, sizeof(state), 1, filePointer);
fclose(filePointer);
printf("\nGame with ID:%d saved!", id);
}
int MakeMove(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]) {
char sign = 'X';
if (movesPlayed % 2 == 1){
sign = 'O';
}
int column;
while (1){
printf("\nChoose the column player %c(0 for save and exit): ", sign);
column;
scanf("%d", &column);
if (column >= 0 && column <= 7 && board[0][column-1] == ' '){
break;
}
printf("\nMove not allowed!\n");
}
if (column != 0){
for (int i = 6; i >= 0; i--) {
if (board[i][column-1] == ' ') {
board[i][column-1] = sign;
printf("\n\n\n");
break;
}
}
}else {
SaveGame(board, movesPlayed, player1Name, player2Name);
return 1;
}
return 0;
}
void PlayGame(char board[6][7], char player1Name[20], char player2Name[20], int movesPlayed){
while (1){
PrintBoard(board);
if (MakeMove(board, movesPlayed, player1Name, player2Name) == 1){
break;
}
movesPlayed++;
int result = CheckForWinner(board);
if (result != 0){
PrintBoard(board);
if (result == 1){
printf("\nX wins\n\n\n");
} else {
printf("\nO wins\n\n\n");
}
break;
}
if (movesPlayed == 42){
PrintBoard(board);
printf("\nTie!\n\n\n");
break;
}
}
}
void ListAllSavedGames(){
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
fclose(filePointer);
}
void ListAllPlayerGames(){
char playerName[20];
printf("\nName of player: ");
scanf("%s", playerName);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (strcmp(playerName, state.player1Name) == 0 || strcmp(playerName, state.player2Name) == 0){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
}
fclose(filePointer);
}
int ShowTheBoard(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
printf("\nX: %s, O: %s", state.player1Name, state.player2Name);
PrintBoard(state.board);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
int LoadAGame(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
PlayGame(state.board, state.player1Name, state.player2Name, state.numberOfMoves);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
void ShowLoadMenu(){
int returnToMainMenu = 0;
while (returnToMainMenu == 0){
printf("\n\n\n1. List all saved games\n");
printf("2. List all saved games for a particular player\n");
printf("3. Show the board of one of the saved games\n");
printf("4. Load a game\n");
printf("5. Return to main menu\n");
printf("Choose: ");
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ListAllSavedGames();
break;
case 2:
ListAllPlayerGames();
break;
case 3:
while (ShowTheBoard() == 1){
printf("ID not valid!");
}
break;
case 4:
while (LoadAGame() == 1){
printf("ID not valid!");
}
returnToMainMenu = 1;
break;
case 5:
returnToMainMenu = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
int main(){
int endOfProgram = 0;
while (endOfProgram == 0){
char board[6][7];
char player1Name[20];
char player2Name[20];
int movesPlayed = 0;
ShowMenu();
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ClearBoard(board);
ReadPlayerNames(player1Name, player2Name);
PlayGame(board, player1Name, player2Name, movesPlayed);
break;
case 2:
ShowLoadMenu();
break;
case 3:
printf("Goodbye!");
endOfProgram = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
Culprit is likely to be inside MakeMove:
if (column >= 0 && column <= 7 && board[0][column-1] == ' ') {
break;
}
if you pass 0 as column, the first 2 tests will indeed succeed (both 0 >= 0 and 0 <= 7 are true). But third one tries to use board[0][-1]. -1 is not a valid index and you are invoking UB.
If column is 0, you should not test anything else, so your test should be:
if (column == 0 || (column > 0 && column <= 7
&& board[0][column-1] == ' ')) {
break;
}

sscanf reads what it's not supposed to

I've recently encountered a problem with sscanf(), which I'm using to parse a polynomial.
The problem is, that this sscanf returns 1:
if (sscanf(pTemp, "%lfx\0", &tempBuf)) {
while reading the following:
4x^2\0-4x\01\t\0\0\0\0\0\0\0\0\0
but it's supposed to return 0 (obviously).
And this part of code has successfully read the right thing just before that, so I have no clue on what goes wrong.
I've tried replacing \t with such things, as * /, this didn't help. sscanf keeps recognizing 1(something) as %lfx, while supposed to return 0 and move forward.
What's the problem with it and how can I solve it except rewriting the code without using sscanf?
Here is the code itself(comments and printfs are in Russian, but they don't mean anything to the problem):
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
typedef struct polynom {
double* coeffs;
int power;
} polynom;
void main() {
setlocale(LC_ALL, "RUS");
char bufRead, flagNeg = 0, numExp = 0, xExp = 0, powExp = 0, xNotExp = 0, powAlrSet = 0, *tempReadStr, *pTemp, tempReadC = 0;
int power = 0, apprAcc = 0, cnt = 0, prolongCnt = 0;
double tempBuf = 0;
polynom* polynomIn, * polynomDer, * polynom0;
tempReadStr = calloc(52, sizeof(char));
if (!tempReadStr) {
printf("Не хватает памяти для строки ввода. Попробуйте закрыть все ненужные приложения и повторить попытку.");
return 0;
}
printf("Введите многочлен: ");
//ввод самого многочлена в строку
while (1) {
scanf("%c", &tempReadC);
if (tempReadC == '\n') {
tempReadStr[cnt++] = ' ';
break;
}
if (!isdigit(tempReadC) && (tempReadC != '+') && (tempReadC != '-') && (tempReadC != 'x') && (tempReadC != '^')) {
printf("Недопустимый символ: %c. Проверьте правильность ввода.", tempReadC);
return;
}
else {
if (cnt < 50 + prolongCnt * 50) {
if ((cnt != 0) && (tempReadC == '-')) {
tempReadStr[cnt++] = ' ';
}
if (tempReadC == '+') {
tempReadStr[cnt++] = ' ';
}
else {
tempReadStr[cnt++] = tempReadC;
}
}
else {
pTemp = realloc(tempReadStr, (52 + (++prolongCnt * 50)) * sizeof(char));
if (!pTemp) {
printf("Не хватает памяти для строки ввода. Попробуйте закрыть все ненужные приложения и повторить попытку.");
return 0;
}
tempReadStr = pTemp;
for (int j = 52 + ((prolongCnt - 1) * 50); j < 52 + (prolongCnt * 50); j++) {
tempReadStr[j] = '\0';
}
if ((cnt != 0) && (tempReadC == '-')) {
tempReadStr[cnt++] = ' ';
}
if (tempReadC == '+') {
tempReadStr[cnt++] = ' ';
}
else {
tempReadStr[cnt++] = tempReadC;
}
}
}
}
//printf("\n%s", tempReadStr);
pTemp = strtok(tempReadStr, " ");
//блок интерпретации полученной строки
while (1) {
if (!pTemp) {
break;
}
if (sscanf(pTemp, " ")) {
break;
}
/*if (sscanf(pTemp, "+")) {
}*/
if (sscanf(pTemp, "%lfx^%d", &tempBuf, &power) == 2) {
if (powAlrSet) {
if (polynomIn->power < power) {
printf("Встечена степень, большая, чем первая введённая. Введите многочлен, начиная с наибольшей степени.");
return;
}
else {
polynomIn->coeffs[power] = tempBuf;
}
}
else {
polynomIn = calloc(1, sizeof(polynom));
if (!polynomIn) {
printf("Ошибка выделения памяти.");
return;
}
polynomIn->power = power;
polynomIn->coeffs = calloc(power + 1, sizeof(double));
if (!polynomIn->coeffs) {
printf("Ошибка выделения памяти.");
return;
}
powAlrSet = 1;
polynomIn->coeffs[power] = tempBuf;
}
pTemp = strtok(NULL, " ");
continue;
}
if (sscanf(pTemp, "x^%d", &power)) {
if (powAlrSet) {
if (polynomIn->power < power) {
printf("Встечена степень, большая, чем первая введённая. Введите многочлен, начиная с наибольшей степени.");
return;
}
else {
polynomIn->coeffs[power] = 1;
}
}
else {
polynomIn = calloc(1, sizeof(polynom));
if (!polynomIn) {
printf("Ошибка выделения памяти.");
return;
}
polynomIn->power = power;
polynomIn->coeffs = calloc(power + 1, sizeof(double));
if (!polynomIn->coeffs) {
printf("Ошибка выделения памяти.");
return;
}
powAlrSet = 1;
polynomIn->coeffs[power] = 1;
}
pTemp = strtok(NULL, " ");
continue;
}
if (sscanf(pTemp, "-x^%d", &power)) {
if (powAlrSet) {
if (polynomIn->power < power) {
printf("Встечена степень, большая, чем первая введённая. Введите многочлен, начиная с наибольшей степени.");
return;
}
else {
polynomIn->coeffs[power] = -1;
}
}
else {
polynomIn = calloc(1, sizeof(polynom));
if (!polynomIn) {
printf("Ошибка выделения памяти.");
return;
}
polynomIn->power = power;
polynomIn->coeffs = calloc(power + 1, sizeof(double));
if (!polynomIn->coeffs) {
printf("Ошибка выделения памяти.");
return;
}
powAlrSet = 1;
polynomIn->coeffs[power] = -1;
}
pTemp = strtok(NULL, " ");
continue;
}
if (sscanf(pTemp, "%lfx", &tempBuf)) {
if (powAlrSet) {
polynomIn->coeffs[1] = tempBuf;
}
else {
polynomIn = calloc(1, sizeof(polynom));
if (!polynomIn) {
printf("Ошибка выделения памяти.");
return;
}
polynomIn->power = 1;
polynomIn->coeffs = calloc(2, sizeof(double));
if (!polynomIn->coeffs) {
printf("Ошибка выделения памяти.");
return;
}
powAlrSet = 1;
polynomIn->coeffs[1] = tempBuf;
}
pTemp = strtok(NULL, " ");
continue;
}
if (sscanf(pTemp, "x")) {
if (powAlrSet) {
polynomIn->coeffs[1] = 1;
}
else {
polynomIn = calloc(1, sizeof(polynom));
if (!polynomIn) {
printf("Ошибка выделения памяти.");
return;
}
polynomIn->power = 1;
polynomIn->coeffs = calloc(2, sizeof(double));
if (!polynomIn->coeffs) {
printf("Ошибка выделения памяти.");
return;
}
powAlrSet = 1;
polynomIn->coeffs[1] = 1;
}
pTemp = strtok(NULL, " ");
continue;
}
if (sscanf(pTemp, "-x")) {
if (powAlrSet) {
polynomIn->coeffs[1] = -1;
}
else {
polynomIn = calloc(1, sizeof(polynom));
if (!polynomIn) {
printf("Ошибка выделения памяти.");
return;
}
polynomIn->power = 1;
polynomIn->coeffs = calloc(2, sizeof(double));
if (!polynomIn->coeffs) {
printf("Ошибка выделения памяти.");
return;
}
powAlrSet = 1;
polynomIn->coeffs[1] = -1;
}
pTemp = strtok(NULL, " ");
continue;
}
if (sscanf(pTemp, "%lf", &tempBuf)) {
if (!powAlrSet) {
printf("Ввод многочлена принято начинать со старшей степени.");
return;
}
else {
polynomIn->coeffs[0] = tempBuf;
}
}
}
printf("Вы ввели многочлен:\n");
for (int i = power; i >= 0; i--) {
if (polynomIn->coeffs[i]) { // != 0
if ((polynomIn->coeffs[i] > 0) && (i != power))
printf("+");
if (i) { // != 0
if (polynomIn->coeffs[i] != 1) {
if (polynomIn->coeffs[i] != -1) {
if (i != 1) {
printf("%.0lfx^%d", polynomIn->coeffs[i], i);
}
else printf("%.0lfx", polynomIn->coeffs[i]);
}
else if (i != 1) {
printf("-x^%d", i);
}
else printf("-x");
}
else if (i != 1) {
printf("x^%d", i);
}
else printf("x");
}
else {
if (polynomIn->coeffs[i]) {
printf("%.0lf", polynomIn->coeffs[i]);
}
}
}
}
}
It should give you the polynomial you enter. I tried with 4x^2-4x+1, and it gave me 4x^2+x.
Well, I don't know, what's the reason with sscanf(), because it tends to ignore even what goes before the first formatted input, so I've just replaced all my "-", "x", "^", with %c scanning chars to variables, which values I've checked right after that. And that worked.

C Calculator Program with Stack

Hi I am completely stuck on this basic calculator. It runs almost perfectly but something goes wrong in the stack when I try inputting "5 / 5 + 9 * 2". The 1 from 5 / 5 seems to disappear when it is supposed to be addes to the 18 for the last loop. Happens for simular inputs like 2 * 2 - 9 / 2. Just need help finding this weird error that I have spent many hours trying to figure out with no luck! Thank you!
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <limits.h>
#include <curses.h>
#include<ctype.h>
struct StackNode
{
char* data;
struct StackNode* next;
};
struct StackNode* newNode(char* data)
{
struct StackNode* stackNode =
(struct StackNode*) malloc(sizeof(struct StackNode));
stackNode->data = data;
stackNode->next = NULL;
return stackNode;
}
int isEmpty(struct StackNode *root)
{
return !root;
}
void push(struct StackNode** root, char* data)
{
struct StackNode* stackNode = newNode(data);
stackNode->next = *root;
*root = stackNode;
printf("%s pushed to stack\n", data);
}
char* pop(struct StackNode** root)
{
if (isEmpty(*root))
return NULL;
struct StackNode* temp = *root;
*root = (*root)->next;
char* popped = temp->data;
free(temp);
printf("Popped: %s\n", popped);
return popped;
}
char* peek(struct StackNode* root)
{
if (isEmpty(root))
return NULL;
return root->data;
}
char buffer[64];
char *ca = &buffer[0];
size_t size = 64;
int bufferIndex;
int first = 0;
int isWhiteSpace (char c) {
if ((c == ' ') || (c == '\t') || (c == '\r')) {
return 1;
}
else {
return 0;
}
}
char* getToken() {
char* token = malloc(64);
int i = 0;
while ((isWhiteSpace(buffer[bufferIndex])) && bufferIndex < strlen(buffer)-1) {
bufferIndex++;
}
while (bufferIndex < strlen(buffer)-1) {
int num = isWhiteSpace(buffer[bufferIndex]);
if (num == 0) {
token[i] = buffer[bufferIndex];
i++;
bufferIndex++;
//printf("%s\n", token);
}
else {
bufferIndex++;
break;
}
}
token[i] = '\0';
first++;
return token;
}
int main() {
while (1) {
char* token = "test";
char* postFix = "test";
char* hold = malloc(64);
postFix = malloc(64);
int total = 0;
int pres1 = 0;
int pres2 = 0;
struct StackNode* root = NULL;
printf("Enter line: ");
getline(&ca,&size,stdin);
bufferIndex = 0;
if ((strcmp(token, "quit") == 0)) {
token = getToken();
if (strcmp(token, "") == 0) {
break;
}
else {
printf("Too many arguments. Try again.\n");
}
}
else {
while (strcmp(token, "") != 0) {
token = getToken();
//printf("%s\n", token);
//printf("Top of stack: %s\n", peek(root));
if (isdigit(*token) == 1) {
strcat(postFix, token);
strcat(postFix, " ");
printf("%s\n", postFix);
}
else if (peek(root) == NULL) {
push(&root, token);
}
else {
printf("Peek: %s\n", peek(root));
if (strcmp(token, "*") == 0) {
pres1 = 2;
}
else if (strcmp(token, "/") == 0) {
pres1 = 2;
}
else if (strcmp(token, "-") == 0) {
pres1 = 1;
}
else if (strcmp(token, "+") == 0) {
pres1 = 1;
}
else {
pres1 = 0;
}
if (strcmp(peek(root), "*") == 0) {
pres2 = 2;
}
else if (strcmp(peek(root), "/") == 0) {
pres2 = 2;
}
else if (strcmp(peek(root), "-") == 0) {
pres2 = 1;
}
else if (strcmp(peek(root), "+") == 0) {
pres2 = 1;
}
while((peek(root) != NULL) && (pres2 > pres1)) {
strcat(postFix, peek(root));
strcat(postFix, " ");
pop(&root);
printf("Postfix: %s\n", postFix);
}
push(&root, token);
}
}
do {
//printf("Peek in DO/WHILE: %s\n", peek(root));
strcat(postFix, peek(root));
strcat(postFix, " ");
pop(&root);
} while ((peek(root) != NULL));
printf("Postfix: %s\n", postFix);
//ca = NULL;
token = "1";
bufferIndex = 0;
for (int i = 0; i < strlen(postFix) + 1; i++) {
buffer[i] = postFix[i];
}
//size = strlen(postFix)+1;
//printf("TOKEN: %s\n", token);
while (strcmp(token, "") != 0) {
token = getToken();
if (isdigit(*token) == 1) {
//printf("--Token: %s\n", token);
push(&root, token);
}
else {
int operand1;
//operand1 = malloc(64);
int operand2;
//total = malloc(64);
printf("Peek: %s\n", peek(root));
operand2 = atoi(peek(root));
pop(&root);
printf("Operand2: %d\n", operand2);
if (strcmp(token, "") != 0) {
printf("Peek: %s\n", peek(root));
operand1 = atoi(peek(root));
pop(&root);
printf("Operand1: %d\n", operand1);
printf("Token: %s\n", token);
if (strcmp(token, "+") == 0) {
total = operand1 + operand2;
}
else if (strcmp(token, "/") == 0) {
total = operand1 / operand2;
}
else if (strcmp(token, "-") == 0) {
total = operand1 - operand2;
}
else if (strcmp(token, "*") == 0) {
total = operand1 * operand2;
}
sprintf(hold,"%d",total);
//printf("Peek: %s\n", peek(root));
push(&root, hold);
//pop(&root);
printf("Total: %d\n", total);
}
else {
//printf("Peek: %s\n", peek(root));
break;
}
}
}
}
printf("Total: %d\n", total);
}
return 0;
}
I am supposed to/am using this as a reference for the assignment: http://condor.depaul.edu/ichu/csc415/notes/notes9/Infix.htm
isdigit() should only be tested for zeroness
Instead of:
if (isdigit(*token) == 1) {
use:
if (isdigit((unsigned char)*token)) {
pointers make it easy to overwrite memory used elsewhere
The code does:
char* hold = malloc(64);
and then later on loops doing:
while (/* ... */) {
// ...
sprintf(hold,"%d",total);
push(&root, hold);
// ...
}
This causes all the values stored on the stack to share the same storage and to be overwritten whenever hold is changed.
The allocation must happen on every use:
char *hold;
// ...
while (/* ... */) {
// ...
hold = malloc(64);
sprintf(hold,"%d",total);
push(&root, hold);
// ...
}

Double pointer wont store pointer value correctly and not freeing right

Im using a series of double pointers that point to other double pointers.
Currently i have a struct that points to other structs that have double pointers.
I was using the "sprintf" command to store values and it was working great until i encountered a seg fault.
sprintf(a->cs[a->structCount].fs[sFunCount].parameterType[insideParam],
"%s", a->array);
I got rid of the sprintf and just made it equal to a->array and it worked. But it doesnt store it correctly.
a->cs[a->structCount].fs[sFunCount].parameterType[insideParam] = a->type;
It just keep printing out "int" instead of anything else. When i do
a->cs[a->structCount].fs[sFunCount].parameterType[insideParam] = "double";
It stores it correctly.
Can you also advise me if im mallocing all my arrays correctly and if im freeing them correctly as well.
Heres all my code..
#include "header.h"
int main(int argc, char * argv[]){
all * a;
if(argc != 2){
printf("Error: Send input file as command line argument.\n");
return 1;
}
display(argv[1]);
a = openFile(argv[1]);
printProgram(a);
freeMe(a);
return 0;
}
all * openFile(char * fileName){
FILE *fp;
int token = 0, z = 0, x = 0, j = 0, i = 0, dotSwitch = 0,
hashSwitch = 0, leftPacSwitch = 0, varNCount = 0, funNCount = 0,
parameter = 0, parameterName = 0, rightBrace = 0, leftBrace = 0,
structNameSwitch = 0, insideStruct = 0, globalCount = 0,
funRightBrace = 0, funLeftBrace = 0, sFunCount = 0, insideParam = 0;
all * a = malloc(sizeof(all));
switches * s = malloc(sizeof(switches));
//a = m(a);
s->structSwitch = 0;
s->functionSwitch = 0;
s->variableSwitch = 0;
s->commentSwitch = 0;
s->quoteSwitch = 0;
s->slashSwitch = 0;
s->nameSwitch = 0;
s->bracketSwitch = 0;
a->hashCount = 0;
a->cs = malloc(sizeof(cStruct *) * 100);
a->fs = malloc(sizeof(fStruct *) * 100);
a->globalVariableType = malloc(sizeof(char *) * 100);
a->globalVariableName = malloc(sizeof(char *) * 100);
a->includes = malloc(sizeof(char *) * 100);
a->array = malloc(sizeof(char));
a->type = malloc(sizeof(char));
a->vName = malloc(sizeof(char));
a->preDot = malloc(sizeof(char));
a->prePac = malloc(sizeof(char));
a->structName = malloc(sizeof(char));
a->structCount = 0;
a->cs[a->structCount].variableCount = 0;
for(i = 0; i < 100; i++){
a->cs[i].name = malloc(sizeof(char)*50);
a->cs[i].variableType = malloc(sizeof(char)*50);
a->cs[i].variableName = malloc(sizeof(char)*50);
a->cs[i].fs = malloc(sizeof(fStruct)*50);
a->fs[i].functionName = malloc(sizeof(char)*50);
a->fs[i].functionType = malloc(sizeof(char)*50);
a->fs[i].parameterName = malloc(sizeof(char)*50);
a->fs[i].parameterType = malloc(sizeof(char)*50);
a->globalVariableName[i] = malloc(sizeof(char)*50);
a->globalVariableType[i] = malloc(sizeof(char)*50);
a->includes[i] = malloc(sizeof(char)*50);
for(x = 0; x < 100; x++){
a->cs[i].variableType[x] = malloc(sizeof(char)*50);
a->cs[i].variableName[x] = malloc(sizeof(char)*50);
a->cs[i].fs[x].functionName = malloc(sizeof(char)*50);
a->cs[i].fs[x].functionType = malloc(sizeof(char)*50);
a->cs[i].fs[x].parameterType = malloc(sizeof(char)*50);
a->cs[i].fs[x].parameterName = malloc(sizeof(char)*50);
a->fs[i].parameterName[x] = malloc(sizeof(char)*50);
a->fs[i].parameterType[x] = malloc(sizeof(char)*50);
for(z = 0; z < 100; z++){
a->cs[i].fs[x].parameterType[z] = malloc(sizeof(char)*50);
a->cs[i].fs[x].parameterName[z] = malloc(sizeof(char)*50);
}
}
}
//Opening the file
fp = fopen(fileName,"r");
//If file doesnt exist then display output
if(fp == NULL){
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
else{
printf("\nUpdated File(C):\n");
}
while((token = fgetc(fp)) != EOF){
if(token != ' ' && token != '{' && token != '}' && token != ';' && token != '\n' && token != '(' && token != ')' && token != '/' && token != '"' && token != '*' && token != '\\' && token != ',' && token != '.' && token != '>' && token != '#'){
a->array[j] = token;
j++;
}
else{
if(token == '/'){
s->commentSwitch++;
printf("/");
}
else if(token == '>'){
sprintf(a->prePac,"%s%c", a->array, token);
leftPacSwitch = 1;
}
else if(token == '#'){
hashSwitch = 1;
}
else if(token == '.'){
sprintf(a->preDot,"%s%c", a->array, token);
dotSwitch = 1;
}
else if(token == '{' && s->structSwitch == 1 && structNameSwitch == 0){
sprintf(a->cs[a->structCount].name,"%s", a->structName);
//structCount++;
rightBrace++;
printf("%c", token);
structNameSwitch = 1;
insideStruct = 1;
}
else if (token == '{' && s->structSwitch == 1){
rightBrace++;
a->cs[a->structCount].rightBracket = rightBrace;
if (s->structFunctionSwitch == 1){
funRightBrace++;
a->cs[a->structCount].fs[funRightBrace].rightBracket = funRightBrace;
}
printf("%c", token);
}
else if(token == '}' && s->structSwitch == 1){
leftBrace++;
if(rightBrace == leftBrace){
s->structSwitch = 0;
rightBrace = 0;
leftBrace = 0;
insideStruct = 0;
sFunCount = 0;
a->structCount++;
}
else if (s->structFunctionSwitch == 1){
funLeftBrace++;
a->cs[a->structCount].fs[funLeftBrace].leftBracket = funLeftBrace;
if(funRightBrace == funLeftBrace){
s->structFunctionSwitch = 0;
funRightBrace = 0;
funLeftBrace = 0;
}
}
printf("%c", token);
}
else if(token == '\\'){
s->slashSwitch = 1;
s->quoteSwitch = 0;
printf("%s", a->array);
printf("%c", token);
}
else if(token == '(' && s->variableSwitch == 1 && s->structSwitch == 0){
s->bracketSwitch = 1;
sprintf(a->fs[funNCount].functionType, "%s", a->type);
sprintf(a->fs[funNCount].functionName, "%s", a->array);
funNCount++;
printf("%s", a->array);
printf("%c", token);
}
else if(token == '(' && insideStruct == 1 && s->variableSwitch == 1){
s->bracketSwitch = 1;
insideParam = 0;
printf("%s",a->array);
printf("%c", token);
sprintf(a->cs[a->structCount].fs[sFunCount].functionType, "%s", a->type);
sprintf(a->cs[a->structCount].fs[sFunCount].functionName, "%s", a->array);
s->structFunctionSwitch = 1;
s->variableSwitch = 0;
s->nameSwitch = 0;
a->cs[a->structCount].functionCount = sFunCount;
}
else if(token == ')' && insideStruct == 1 && s->bracketSwitch == 1){
s->bracketSwitch = 0;
s->structFunctionSwitch = 0;
a->cs[a->structCount].fs[sFunCount].parameterName[insideParam] = a->array;
a->cs[a->structCount].fs[sFunCount].parameterType[insideParam] = a->type;
printf("%d",insideParam);
a->cs[a->structCount].fs[sFunCount].paraCount = insideParam;
// printf("s: %d , f: %d, i: %d\n", a->structCount,sFunCount,insideParam);
// printf("%s\n", a->cs[a->structCount].fs[sFunCount].parameterName[insideParam]);
printf("%s", a->array);
printf("%c", token);
sFunCount++;
}
else if(token == ')' && s->variableSwitch == 1){
sprintf(a->fs[funNCount].parameterName[a->fs[funNCount].paraCount], "%s", a->array);
parameterName++;
printf("%s",a->array);
printf("%c", token);
s->bracketSwitch = 0;
s->variableSwitch = 0;
parameter = 0;
}
else if(token == '*'){
printf("%s", a->array);
printf("%c", token);
}
else if(s->commentSwitch == 2){
printf("%s",a->array);
printf("%c", token);
if(token == '\n'){
s->commentSwitch = 0;
}
}
else if(s->slashSwitch == 1){
printf("%s",a->array);
printf("%c", token);
s->slashSwitch = 0;
}
else if(token == '"' && s->slashSwitch == 0 && s->commentSwitch == 0){
s->quoteSwitch++;
printf("%s",a->array);
printf("%c", token);
if(s->quoteSwitch == 2){
s->quoteSwitch = 0;
}
}
else if(s->quoteSwitch == 1 && token != '"'){
printf("%s",a->array);
printf("%c", token);
}
else{
if(hashSwitch == 1 && dotSwitch == 1 && leftPacSwitch == 1){
printf("#%s%s", a->preDot,a->prePac);
sprintf(a->includes[a->hashCount], "%s%s", a->preDot,a->prePac);
a->hashCount++;
hashSwitch = 0;
dotSwitch = 0;
leftPacSwitch = 0;
}
else if(strcmp(a->array,"class") == 0 && s->commentSwitch != 2 && s->quoteSwitch != 1){
strcpy(a->array,"struct");
s->structSwitch = 1;
structNameSwitch = 0;
varNCount = 0;
}
else if(s->structSwitch == 1 && insideStruct == 1){
if(strcmp(a->array,"int") == 0 || strcmp(a->array,"double") == 0 || strcmp(a->array,"float") == 0 || strcmp(a->array,"char") == 0 || strcmp(a->array,"void") == 0){
if(s->bracketSwitch == 0 ){
strcpy(a->type,a->array);
s->variableSwitch = 1;
s->nameSwitch = 0;
}
else if(s->bracketSwitch == 1){
// printf("vjjkjj");
a->cs[0].fs[0].parameterType[4] = a->type;
strcpy(a->type,a->array);
s->variableSwitch = 0;
s->nameSwitch = 0;
s->structFunctionSwitch = 1;
insideParam++;
a->cs[a->structCount].fs[sFunCount].paraCount++;
}
// printf("var1: %d nam: %d Bra: %d fun: %d inside: %d st: %d\n", s->variableSwitch, s->nameSwitch,s->bracketSwitch, s->structFunctionSwitch, insideStruct, s->structSwitch);
/*else{
s->variableSwitch = 0;
}*/
}
//Gets all the variables in the struct
else if(s->nameSwitch == 0 && s->variableSwitch == 1 && s->bracketSwitch == 0){
varNCount++;
strcpy(a->vName,a->array);
a->cs[a->structCount].variableCount = varNCount;
sprintf(a->cs[a->structCount].variableType[varNCount], "%s", a->type);
sprintf(a->cs[a->structCount].variableName[varNCount], "%s", a->vName);
s->variableSwitch = 0;
}
else if(s->nameSwitch == 0 && s->variableSwitch == 0 && s->bracketSwitch == 1 && s->structFunctionSwitch == 1){
a->cs[a->structCount].fs[sFunCount].parameterType[insideParam] = a->type;
a->cs[a->structCount].fs[sFunCount].parameterName[insideParam] = a->array;
if(strcmp(a->type, "double") == 0){
a->cs[a->structCount].fs[sFunCount].parameterType[insideParam] = "double";;
}
a->cs[1].fs[0].parameterType[3] = "double";
a->cs[1].fs[0].parameterName[3] = "gg";
printf("struct: %s\n", a->type);
//printf("structh: %d, Function: %d, Param: %d", a->structCount, sFunCount, insideParam);
// a->cs[a->structCount].fs[sFunCount].paraCount = insideParam;
// printf("HAHA%d", a->cs[a->structCount].fs[sFunCount].paraCount);
s->nameSwitch = 1;
}
}
else if(s->structSwitch == 1 && structNameSwitch == 0){
strcpy(a->structName,a->array);
}
else if(strcmp(a->array,"int") == 0 || strcmp(a->array,"double") == 0 || strcmp(a->array,"float") == 0 || strcmp(a->array,"char") == 0 || strcmp(a->array,"void") == 0){
if(s->bracketSwitch == 1){
sprintf(a->fs[funNCount].parameterType[parameter], "%s", a->array);
a->fs[funNCount].paraCount = parameter;
parameter++;
}
else{
strcpy(a->type,a->array);
}
s->variableSwitch = 1;
s->nameSwitch = 0;
}
else if(s->variableSwitch == 1 && s->nameSwitch == 0){
if(s->bracketSwitch == 1){
sprintf(a->fs[funNCount].parameterName[a->fs[funNCount].paraCount], "%s", a->array);
parameterName++;
}
else{
strcpy(a->vName,a->array);
}
s->nameSwitch = 1;
}
else if(s->variableSwitch == 1 && s->nameSwitch == 1 && s->bracketSwitch == 0){
sprintf(a->globalVariableType[globalCount], "%s", a->type);
sprintf(a->globalVariableName[globalCount], "%s", a->vName);
a->globalCount = globalCount;
globalCount++;
s->variableSwitch = 0;
s->nameSwitch = 0;
}
printf("%s",a->array);
printf("%c", token);
}
memset(a->array,0,strlen(a->array));
j = 0;
}
}
a->funCount = funNCount;
printf("%d\n\n",a->fs[2].paraCount);
printf("{ : %d\n", rightBrace);
printf("} : %d\n", leftBrace);
fclose(fp);
return a;
}
int fOrV(char * c){
int len = strlen(c), i;
//char * array = malloc(sizeof(char*));
for(i = 0;i < len; i++){
if(c[i] == '('){
return 1;
}
else if(c[i] == ')' || c[i] == ','){
//printf("LOOL %s\n",c);
return 2;
}
}
return 0;
}
int display(char * fileName){
FILE *fp;
char * array;
int token = 0, totalStruct = 0, totalVariable = 0, j = 0;
array = malloc(sizeof(char));
//Opening the file
fp = fopen(fileName,"r");
//If file doesnt exist then display output
if(fp == NULL){
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
else{
printf("File %s opened successfully\nOriginal Code(C++):\n", fileName);
}
while((token = fgetc(fp)) != EOF){
if(token != ' ' && token != '{' && token != '}' && token != ';' && token != '\n' && token != '(' && token != ')' && token != '/' && token != '"' && token != '*' && token != '\\' && token != ',' && token != '.' && token != '[' && token != ']'){
array[j] = token;
j++;
}
else{
if(strcmp(array,"class") == 0){
totalStruct++;
}
else if(strcmp(array,"int") == 0 || strcmp(array,"double") == 0 || strcmp(array,"float") == 0 || strcmp(array,"char") == 0 || strcmp(array,"void") == 0){
totalVariable++;
}
memset(array,0,strlen(array));
j = 0;
printf("%s",array);
}
printf("%c", token);
}
fclose(fp);
return 0;
}
void printProgram(all * a){
int b, i;
for(b = 0; b < a->structCount; b++){
printf("Struct Name: %s\n", a->cs[b].name);
for(i = 1; i <= a->cs[b].variableCount; i++){
printf("\tVariabe Type: %s %s\n", a->cs[b].variableType[i],a->cs[b].variableName[i]);
}
for(i = 0; i <= a->cs[b].functionCount; i++){
printf("\tFunction Type: %s %s\n", a->cs[b].fs[i].functionType,a->cs[b].fs[i].functionName);
}
}
for(i = 0; i <= a->globalCount; i++){
printf("Global Variable: %s %s\n", a->globalVariableType[i], a->globalVariableName[i]);
}
printf("----------------------------------------------\n");
for(i = 0; i < a->hashCount; i++){
printf("%s\n", a->includes[i]);
}
printf("\n");
for(i = 0; i <= a->globalCount; i++){
printf("%s %s;\n", a->globalVariableType[i], a->globalVariableName[i]);
}
printf("\n");
for(b = 0; b < a->structCount; b++){
printf("struct %s {\n", a->cs[b].name);
for(i = 1; i <= a->cs[b].variableCount; i++){
printf("\t%s %s;\n", a->cs[b].variableType[i],a->cs[b].variableName[i]);
}
for(i = 0; i <= a->cs[b].functionCount; i++){
printf("\t%s (*%s%s)();\n", a->cs[b].fs[i].functionType,a->cs[b].name,a->cs[b].fs[i].functionName);
}
printf("}\n");
}
printf("WHAT: %s\n", a->cs[0].fs[0].parameterType[3]);
int x;
for(b = 0; b < a->structCount; b++){
// printf("S: %d", b);
for(i = 0; i <= a->cs[b].functionCount; i++){
//printf("F: %d", i);
printf("%s %s%s(", a->cs[b].fs[i].functionType,a->cs[b].name,a->cs[b].fs[i].functionName);
for(x = 1; x <= a->cs[b].fs[i].paraCount; x++){
//printf("F: %d\n", x);
if(x == (a->cs[b].fs[i].paraCount)){
printf("%s %s", a->cs[b].fs[i].parameterType[x],a->cs[b].fs[i].parameterName[x]);
}
else if(x == 1){
printf("%s %s,", a->cs[b].fs[i].parameterType[x],a->cs[b].fs[i].parameterName[x]);
}
else{
printf(" %s %s,", a->cs[b].fs[i].parameterType[x],a->cs[b].fs[i].parameterName[x]);
}
}
printf("){\n");
}
printf("\n");
}
for(i = 0; i < a->funCount; i++){
printf("%s %s(", a->fs[i].functionType, a->fs[i].functionName);
for(b = 0; b <= a->fs[i+1].paraCount; b++){
printf("%s %s ", a->fs[i+1].parameterType[b], a->fs[i+1].parameterName[b]);
}
printf("){\n");
}
}
void freeMe(all * a){
int i, x;
/*for(i = 0; i < 100; i++){
free(a->cs[i].name);
free(a->cs[i].variableType);
free(a->cs[i].variableName);
free(a->cs[i].fs);
free(a->fs[i].functionName);
free(a->fs[i].functionType);
free(a->fs[i].parameterName);
free(a->fs[i].parameterType);
free(a->globalVariableName[i]);
free(a->globalVariableType[i]);
free(a->includes[i]);
}
free(a->cs);
free(a->fs);
free(a->globalVariableType);
free(a->globalVariableName);
free(a->includes);
free(a->array);
free(a->type);
free(a->vName);
free(a->preDot);
free(a->prePac);
free(a->structName);*/
free(a);
//free(s);
}
Even without the missing #include "header.h" where all structures were declared, I have used the content of the provided source code to restore the nested-data structure and checked all calls of malloc().
Restored Data - here are all reversed data structures (supposed to come from "header.h")
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct st_fStruct {
char *functionName;
char *functionType;
char **parameterName;
char **parameterType;
int rightBracket;
int leftBracket;
int paraCount;
} fStruct;
typedef struct st_cStruct {
int variableCount;
char *name;
char **variableType;
char **variableName;
fStruct *fs;
int rightBracket;
int functionCount;
} cStruct;
typedef struct st_all {
int hashCount;
cStruct *cs;
fStruct *fs;
char **globalVariableType;
char **globalVariableName;
char **includes;
char *array;
char *type;
char *vName;
char *preDot;
char *prePac;
char *structName;
int structCount;
int globalCount;
int funCount;
} all;
typedef struct st_switches {
int structSwitch;
int functionSwitch;
int variableSwitch;
int commentSwitch;
int quoteSwitch;
int slashSwitch;
int nameSwitch;
int bracketSwitch;
int structFunctionSwitch;
} switches;
int display(char * fileName);
all* openFile(char * fileName);
void printProgram(all* p_all);
void freeMe(all* p_all);
Mallocing Analysis - here are all the provided malloc() and corrected proposal.
Error in the sizeof() items when calling malloc().
a->cs = malloc(sizeof(cStruct *) * 100); // must be sizeof(cStruct)
a->fs = malloc(sizeof(fStruct *) * 100); // must be sizeof(fStruct)
Error allocating only one char for a string.
a->array = malloc(sizeof(char)); // must be (sizeof(char)*50)
a->type = malloc(sizeof(char)); // must be (sizeof(char)*50)
a->vName = malloc(sizeof(char)); // must be (sizeof(char)*50)
a->preDot = malloc(sizeof(char)); // must be (sizeof(char)*50)
a->prePac = malloc(sizeof(char)); // must be (sizeof(char)*50)
a->structName = malloc(sizeof(char)); // must be (sizeof(char)*50)
// in the display function
array = malloc(sizeof(char)); // must be (sizeof(char)*50)
Mitigation between string char * and array of strings char **.
a->cs[i].variableType = malloc(sizeof(char)*50); // must be malloc(sizeof(char *)*100);
a->cs[i].variableName = malloc(sizeof(char)*50); // must be malloc(sizeof(char *)*100);
a->fs[i].parameterName = malloc(sizeof(char)*50); // must be malloc(sizeof(char *)*100);
a->fs[i].parameterType = malloc(sizeof(char)*50); // must be malloc(sizeof(char *)*100);
a->cs[i].fs[x].parameterType = malloc(sizeof(char)*50); // must be malloc(sizeof(char *)*100);
a->cs[i].fs[x].parameterName = malloc(sizeof(char)*50); // must be malloc(sizeof(char *)*100);
Bad size of an array of struct fStruct.
a->cs[i].fs = malloc(sizeof(fStruct)*50); // must be malloc(sizeof(fStruct)*100);
Correct use of malloc() (17/33).
all * a = malloc(sizeof(all));
switches * s = malloc(sizeof(switches));
a->globalVariableType = malloc(sizeof(char *) * 100);
a->globalVariableName = malloc(sizeof(char *) * 100);
a->includes = malloc(sizeof(char *) * 100);
for(i = 0; i < 100; i++){
a->cs[i].name = malloc(sizeof(char)*50);
a->fs[i].functionName = malloc(sizeof(char)*50);
a->fs[i].functionType = malloc(sizeof(char)*50);
a->includes[i] = malloc(sizeof(char)*50);
...
for(x = 0; x < 100; x++){
a->cs[i].variableType[x] = malloc(sizeof(char)*50);
a->cs[i].variableName[x] = malloc(sizeof(char)*50);
a->cs[i].fs[x].functionName = malloc(sizeof(char)*50);
a->cs[i].fs[x].functionType = malloc(sizeof(char)*50);
a->fs[i].parameterName[x] = malloc(sizeof(char)*50);
a->fs[i].parameterType[x] = malloc(sizeof(char)*50);
...
for(z = 0; z < 100; z++){
a->cs[i].fs[x].parameterType[z] = malloc(sizeof(char)*50);
a->cs[i].fs[x].parameterName[z] = malloc(sizeof(char)*50);

Segmentation Fault fgets() two pass assembler [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
#include<string.h>
typedef struct{
char Mnemonic[7];
int code;
} code;
typedef struct{
char label[10];
unsigned int location;
} symbolTab;
int opLook(char * mnemonic, code * optable)
{
int i = 0;
int value = 0;
for(i ; i<25 ; i++)
{
if(strcmp(mnemonic, optable[i].Mnemonic) == 0)
{
value = optable[i].code;
return value;
}
}
return value;
}
int opValid(char * mnemonic, code * optable)
{
int i = 0;
for(i ; i<25 ; i++)
{
if(strcmp(mnemonic, optable[i].Mnemonic) == 0)
{
return 1;
}
}
return 0;
}
int labelcheck(char * label, symbolTab * Table, int counter)
{
int i = 0;
int flag = 0;
if (counter == 0)
{
return flag;
}
else
{
for(i; i <counter; i ++)
{
if(strcmp(label, Table[i].label) == 0)
{
flag = 1;
}
}
return flag;
}
}
unsigned int labelVal(char * label, symbolTab * Table, int counter)
{
int i = 0;
for(i; i <counter; i ++)
{
if(strcmp(label, Table[i].label) == 0)
{
return Table[i].location;
}
}
}
void Assemble(char* filename)
{
unsigned int locctr = 0; /*location counter*/
unsigned int prolen = 0; /*program length*/
int mnemoVal; /*mnemonic Value in Int*/
int labelctr = 0;
code Opta[25] = {{"ADD", 24},{"AND",88},{"COMP",40},{"DIV",36},{"J",60},
{"JEQ",48},{"JGT",52},{"JLT",56},{"JSUB",72},{"LDA",00},
{"LDCH",80},{"LDL", 8},{"LDX", 4},{"MUL",32},{"OR",68},
{"RD",216},{"RSUB",76},{"STA",12},{"STCH",84},{"STL",20},
{"STX",16},{"SUB",28},{"TD",224},{"TIX",44},{"WD",220}};
symbolTab symTab[500];
char buffer[255];
FILE * source;
FILE * interFile;
FILE * objF;
FILE * ListFile;
interFile = fopen("intermidiateFile.txt", "w+");
ListFile = fopen("ListingFile.txt", "w+");
objF = fopen("ObjectFile.txt", "w+");
source = fopen("source.txt", "r");
char * lab; /*label*/
char * mnemo; /*mnemonic*/
char * operand;
char * address = "adress";
unsigned int opeaddress;
fgets(buffer, 255, source);
if (buffer[0] != '.')
{
fprintf(interFile, "%s", buffer);
}
/*Getting first line and initialization of Location Counter*/
if(buffer[0] == '.') /* if the line is a comment continue with the next iteration of the loop*/
{
locctr = 0;
}
else
{
if(buffer[0] == ' ' || buffer[0] == '\t')
{
mnemo = strtok(buffer, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
}
else
{
/*error*/
}
}
else
{
lab =strtok(buffer, " \t");
mnemo = strtok(NULL, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
}
else
{
/*error*/
}
}
}
/* End of the location counter initialization */
/*start while loop*/
while(!feof(source))
{
memset(lab, '\0', strlen(lab));
memset(mnemo, '\0', strlen(mnemo));
memset(operand, '\0', strlen(operand));
fgets(buffer, 255, source);
fprintf(interFile, "%s", buffer);
if(buffer[0] == '.') /* if the line is a comment continue with the next iteration of the loop*/
{
continue;
}
else /* Else for... If it is not a comment, then check if it start with a character or a space*/
{
if(buffer[0] == ' ' || buffer[0] == '\t') /* If it start with a space, then it is just a mnemonic or mnemonic & operand*/
{
mnemo = strtok(buffer, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
if(strcmp(mnemo, "RSUB") == 0)
{
mnemoVal = opLook(mnemo, Opta);
fprintf(interFile, "%x %02x\n", locctr, mnemoVal);
}
else
{
operand = strtok(NULL, " \t\r\n");
mnemoVal = opLook(mnemo, Opta);
fprintf(interFile, "%x %02x %s\n", locctr, mnemoVal, operand);
}
}
else
{
lab = strtok(buffer, " \t\n\r"); /* it has a label, mnemonic and operand*/
if(labelcheck(lab, symTab, labelctr) == 0) /* check if the label is already in the symTab, if not, add it, otherwise it is an error*/
{
strcpy(symTab[labelctr].label, lab);
symTab[labelctr].location = locctr;
labelctr++;
mnemo = strtok(NULL, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
operand = strtok(NULL, " \t\n\r");
mnemoVal = opLook(mnemo, Opta);
}
else
{
mnemo = strtok(NULL, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
operand = strtok(NULL, " \t\n\r");
mnemoVal = opLook(mnemo, Opta);
}
fprintf(interFile, "%x %s %02x %s\n", locctr, lab, mnemoVal, operand);
}
}
if(strcmp(mnemo, "WORD") == 0 )
{
locctr = locctr + 3;
}
else if(strcmp(mnemo, "BYTE") == 0 )
{
unsigned int val;
if (operand[0] =='C')
{
val = strlen(operand) - 3;
locctr = locctr + val;
}
else
{
val = (strlen(operand) - 3)/2;
locctr = locctr + val;
}
}
else if(strcmp(mnemo, "RESB") == 0)
{
locctr = locctr + atoi(operand);
}
else if(strcmp(mnemo, "RESW") == 0)
{
locctr = locctr + (3*atoi(operand));
}
else
{
locctr= locctr + 3;
}
}
/* End of While loop*/
prolen = locctr - symTab[0].location;
fprintf(interFile, "\n%x", prolen);
fclose(source);
fclose(interFile);
interFile = fopen("intermidiateFile.txt", "r");
/*Start the Listing File and Object File ---------------------Pass 2----------- */
fgets(buffer, 255, interFile);
if(buffer[0] == '.') /* if the line is a comment continue with the next iteration of the loop*/
{
locctr = 0;
/*Error missung Start or Misplaced*/
}
else
{
if(buffer[0] == ' ' || buffer[0] == '\t')
{
mnemo = strtok(buffer, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
strcpy(address, operand);
fprintf(ListFile, "%X %s %s\n", locctr, mnemo, operand);
}
else
{
/*error*/
}
}
else
{
lab =strtok(buffer, " \t");
mnemo = strtok(NULL, " \t");
operand = strtok(NULL, " \t");
if(strcmp(mnemo, "START") == 0)
{
locctr = strtol(operand, NULL, 16);
fprintf(ListFile, "%x %s %s %s\n", locctr, lab, mnemo, operand);
fprintf(objF, "H%s__%06x%06x\n", lab, locctr, prolen);
}
else
{
/*error*/
}
}
}
while(!feof(interFile))
{
memset(lab, '\0', strlen(lab));
memset(mnemo, '\0', strlen(mnemo));
memset(operand, '\0', strlen(operand));
memset(address, '\0', strlen(address));
memset(buffer, '\0', strlen(buffer));
fgets(buffer, 255, interFile);
if (buffer[0] == '\r')
{
continue;
}
if(buffer[0] == ' ' || buffer[0] == '\t')
{
mnemo = strtok(buffer, " \t\n\r");
if (strcmp(mnemo, "END") == 0)
{
break;
}
if(strcmp(mnemo, "RSUB") == 0)
{
memset(buffer, '\0', strlen(buffer));
fgets(address, 255, interFile);
mnemoVal = opLook(mnemo, Opta);
fprintf(ListFile, "%s %s %X0000", address, mnemo, mnemoVal);
}
else
{
operand = strtok(NULL, " \t\r\n");
mnemoVal = opLook(mnemo, Opta);
memset(buffer, '\0', strlen(buffer));
fgets(address, 255, interFile);
if (labelcheck(operand, symTab, labelctr) == 1)
{
opeaddress = labelVal(operand, symTab, labelctr);
}
else
{
opeaddress = 0;
/* error*/
}
fprintf(ListFile, "%s %s %s %02X%04X", address, mnemo, operand, mnemoVal, opeaddress);
}
}
else if (buffer[0] == '.')
{
fprintf(ListFile, "%s\n", buffer);
}
else
{
lab = strtok(buffer, " \t\n\r");
mnemo = strtok(NULL, " \t\n\r");
operand = strtok(NULL, " \t\n\r");
mnemoVal = opLook(mnemo, Opta);
memset(buffer, '\0', strlen(buffer));
fgets(address, 255, interFile);
if (labelcheck(operand, symTab, labelctr) == 1)
{
opeaddress = labelVal(operand, symTab, labelctr);
}
else
{
opeaddress = 0;
/* error*/
}
fprintf(ListFile, "%s %s %s %s %02X%04X", address, lab, mnemo, operand, mnemoVal, opeaddress);
}
}
fclose(interFile);
fclose(objF);
fclose(ListFile);
}
The error occurs in the last while loop when executing fgets();
I have looked if I had any variable or syntax wrong, but everything looks fine.
This is a part of a two pass assemble. The error varies between the fgets in the last while loop. At first I thought that it was the memset function, but the error still happened when I mark them as comments
Because of
char * address = "adress";
address is pointing to Read Only Memory
Trying to modify string literals (in your case "adress") invokes undefined behavior.
Then in your last loop
strcpy(address, operand);
memset(address, '\0', strlen(address));
fgets(address, 255, interFile);
Are wrong.
You could change that variable to a simple array of chars with enough room for your needs, e.g.:
char address[128];

Resources