How to pass array to a function that writes to a file - c

I have this long program and I need to write an array to a file but I'm having issues creating a function that passes array to it so I can write to file without redoing it every time.
This is what I want the function to be but I'm having issues passing the array to it.
the whole part of the program for this functionallity is at bottom plus contents of the file that the program needs to be able to run
void wtf(char *array)
{
int fdi = open("board.txt", O_RDWR);
char msg[1] = "\n";
char msg1[1] = ",";
char msg2[1] = " ";
int i = 0;
int j = 0;
char *neg4 = "-4";
char *neg2 = "-2";
char *neg3 = "-3";
char *neg5 = "-5";
char *neg6 = "-6";
char *neg1 = "-1";
char *cero = "+0";
char *pls4 = "+4";
char *pls2 = "+2";
char *pls3 = "+3";
char *pls5 = "+5";
char *pls6 = "+6";
char *pls1 = "+1";
char *table[8][8] = {{NULL}};
if (fdi != -1)
{
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
if ((strcmp(table[i][j], neg4) == 0) || (strcmp(table[i][j], neg3) == 0) || (strcmp(table[i][j], neg2) == 0) ||
(strcmp(table[i][j], neg5) == 0) || (strcmp(table[i][j], neg6) == 0) || (strcmp(table[i][j], neg1) == 0))
{
write(fdi, table[i][j], strlen(table[i][j]));
}
else if ((strcmp(table[i][j], pls4) == 0) || (strcmp(table[i][j], pls3) == 0) || (strcmp(table[i][j], pls2) == 0) ||
(strcmp(table[i][j], pls5) == 0) || (strcmp(table[i][j], pls6) == 0) || (strcmp(table[i][j], pls1) == 0))
{
write(fdi, table[i][j], strlen(table[i][j]));
}
else // if (strcmp(table[i][j], cero) == 0)
{
write(fdi, msg2, sizeof(msg2));
write(fdi, table[i][j], strlen(table[i][j]));
}
if (j <= 6)
{
write(fdi, msg1, sizeof(msg1));
}
}
write(fdi, msg, sizeof(msg));
}
close(fdi);
}
}
the code..
#include <stdio.h>
#include <stdlib.h> // For exit() function
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#define MAXC 1024
void wtf(char *array);
int main()
{
char c[1000];
char ch[1000];
FILE *fp, *fd, *op;
char word[1000], *token;
char *table[8][8] = {{NULL}};
int i = 0;
int j = 0;
char input[50];
char *endPos, *begPos;
char *buffer;
char *exit = "exit";
char *show = "show";
char *move = "mv";
char *cp = "cp";
char *prq = "prq";
char *prr = "prq";
char *prb = "prb";
char *prk = "prk";
char *neg4 = "-4";
char *neg2 = "-2";
char *neg3 = "-3";
char *neg5 = "-5";
char *neg6 = "-6";
char *neg1 = "-1";
char *cero = "0";
char *pls4 = "+4";
char *pls2 = "+2";
char *pls3 = "+3";
char *pls5 = "+5";
char *pls6 = "+6";
char *pls1 = "+1";
char *one = "1";
char msg[1] = "\n";
char msg1[1] = ",";
char msg2[1] = " ";
char msg3[1] = "+";
char msg4[1] = "-";
char yes[4] = "yes";
int a0Row, b0Col, a1Row, b1Col;
int fdi;
int flag = 0;
size_t len = 10;
if ((fp = fopen("board.txt", "r")) == NULL)
{
printf("Error! opening file");
return 0;
}
//fill array
while (fscanf(fp, "%3s", c) != EOF)
{
token = strtok(c, ",");
len = strlen(token);
//printf("%s ", token);
table[i][j] = malloc(len + 1);
memcpy(table[i][j++], token, len + 1);
if (j >= 8)
{
i++;
j = 0;
//printf("\n");
}
}
printf("\n\n\n");
for (i = 0; i < 8; i++)
{
//printf("\n");
for (j = 0; j < 8; j++)
{
printf("%s ", table[i][j]);
}
printf("\n");
}
fclose(fp);
fdi = open("new.txt", O_RDWR);
if (fdi != -1)
{
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
if ((strcmp(table[i][j], neg4) == 0) || (strcmp(table[i][j], neg3) == 0) || (strcmp(table[i][j], neg2) == 0) ||
(strcmp(table[i][j], neg5) == 0) || (strcmp(table[i][j], neg6) == 0) || (strcmp(table[i][j], neg1) == 0))
{
write(fdi, table[i][j], strlen(table[i][j]));
}
else if ((strcmp(table[i][j], pls4) == 0) || (strcmp(table[i][j], pls3) == 0) || (strcmp(table[i][j], pls2) == 0) ||
(strcmp(table[i][j], pls5) == 0) || (strcmp(table[i][j], pls6) == 0) || (strcmp(table[i][j], pls1) == 0))
{
write(fdi, table[i][j], strlen(table[i][j]));
}
else
{
write(fdi, msg2, sizeof(msg2));
write(fdi, table[i][j], strlen(table[i][j]));
}
if (j <= 6)
{
write(fdi, msg1, sizeof(msg1));
}
}
write(fdi, msg, sizeof(msg));
}
close(fdi);
}
return 0;
}
contents of file board.txt so program can run
-4,-2,-3,-5,-6,-3,-2,-4
-1,-1,-1,-1,-1,-1,-1,-1
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0
+1,+1,+1,+1,+1,+1,+1,+1
+4,+2,+3,+5,+6,+3,+2,+4
I'm sure its probably very ineficient, just learning
Thanks for any input.
update:added errors I get
when I try doing
wtf(table)
compiler says
warning: passing argument 1 of 'wtf' from incompatible pointer type [-Wincompatible-pointer-types]
wtf(table);
^~~~~
chess.c:8:16: note: expected 'char *' but argument is of type 'char * (*)[8]'
void wtf(char *array);
then I try
wtf(*table)
compiler says
chess.c:586:18: warning: passing argument 1 of 'wtf' from incompatible pointer type [-Wincompatible-pointer-types]
wtf(*table);
^~~~~
chess.c:8:16: note: expected 'char *' but argument is of type 'char **'
void wtf(char *array);
~~~~~~^~~~~

There were a number of errors, including warnings about unused variables.
Too many to enumerate them, but ...
wtf had it's own table and not the one read by main.
It looks as though you tried to put the wtf into main when you couldn't pass the table array correctly.
Plus, doing neg1, neg2, ... instead of an array: char neg[6] makes the code needlessly complicated. Likewise for pls*
Also, neg* and pls* were being replicated in both functions. I've moved them to globals for compactness and speed. After doing this, I realized they could go [back] to wtf but having them as global is actually faster.
I fixed the table array passing to wtf [which was your main issue, I believe].
I refactored your program. It is still incomplete [and probably still a bit broken], but it should get you a bit further:
#include <stdio.h>
#include <stdlib.h> // For exit() function
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#define MAXC 1024
#if 0
char msg[1] = "\n";
char msg1[1] = ",";
char msg2[1] = " ";
char msg3[1] = "+";
char msg4[1] = "-";
#else
const char *msg[5] = {
"\n", ",", " ", "+", "-"
};
#endif
#if 0
const char *neg1 = "-1";
const char *neg4 = "-4";
const char *neg2 = "-2";
const char *neg3 = "-3";
const char *neg5 = "-5";
const char *neg6 = "-6";
#else
const char *neg[6] = {
"-1", "-2", "-3", "-4", "-5", "-6"
};
#endif
//const char *cero = "+0";
#if 0
const char *pls4 = "+4";
const char *pls2 = "+2";
const char *pls3 = "+3";
const char *pls5 = "+5";
const char *pls6 = "+6";
const char *pls1 = "+1";
#else
const char *pls[6] = {
"+1", "+2", "+3", "+4", "+5", "+6"
};
#endif
const char *exitmsg = "exit";
const char *show = "show";
const char *move = "mv";
const char *cp = "cp";
const char *prq = "prq";
const char *prr = "prq";
const char *prb = "prb";
const char *prk = "prk";
const char *cero = "0";
const char *one = "1";
char yes[4] = "yes";
#define ARRSIZE(_arr) (sizeof(_arr) / sizeof((_arr)[0]))
void
write_string(int fdo,const char *str)
{
int len = strlen(str);
write(fdo,str,len);
}
void
wtf(int fdo,char *table[8][8])
{
int i = 0;
int j = 0;
#if 0
char *table[8][8] = { {NULL} };
#else
char *tab;
#endif
int idx;
int match;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
tab = table[i][j];
do {
match = 0;
for (idx = 0; idx < ARRSIZE(neg); ++idx) {
if (strcmp(tab,neg[idx]) == 0) {
write_string(fdo, tab);
match = 1;
break;
}
}
if (match)
break;
for (idx = 0; idx < ARRSIZE(pls); ++idx) {
if (strcmp(tab,pls[idx]) == 0) {
write_string(fdo, tab);
match = 1;
break;
}
}
if (match)
break;
if (strcmp(tab, cero) == 0) {
write_string(fdo, msg[2]);
write_string(fdo, tab);
match = 1;
break;
}
} while (0);
if (j <= 6) {
write_string(fdo, msg[1]);
}
}
write_string(fdo, msg[0]);
}
}
int
main()
{
char c[1000];
char ch[1000];
FILE *fp,
*fd,
*op;
char word[1000],
*token;
char *table[8][8] = { {NULL} };
int i = 0;
int j = 0;
char input[50];
char *endPos,
*begPos;
char *buffer;
int a0Row, b0Col, a1Row, b1Col;
int fdo;
int flag = 0;
char *bp;
size_t len = 10;
if ((fp = fopen("board.txt", "r")) == NULL) {
printf("Error! opening file");
return 0;
}
//fill array
while (1) {
// get a line
bp = fgets(c,sizeof(c),fp);
if (bp == NULL)
break;
// parse all tokens on the line
while (1) {
token = strtok(bp,", \t\n");
bp = NULL;
if (token == NULL)
break;
len = strlen(token);
// printf("%s ", token);
#if 0
table[i][j] = malloc(len + 1);
memcpy(table[i][j++], token, len + 1);
#else
//printf("token='%s'\n",token);
table[i][j++] = strdup(token);
#endif
if (j >= 8) {
i++;
j = 0;
// printf("\n");
}
}
}
fclose(fp);
printf("\n\n\n");
for (i = 0; i < 8; i++) {
// printf("\n");
for (j = 0; j < 8; j++) {
printf("%s ", table[i][j]);
}
printf("\n");
}
fdo = open("new.txt", O_WRONLY | O_CREAT,0644);
if (fdo == -1) {
perror("new.txt");
return 1;
}
wtf(fdo,table);
close(fdo);
return 0;
}

Related

I am trying to write SQL part for CSV in C. Why will the code below distort result without duplicating TCHAR * arguments?

The code I write is in C on Visual studio 2022.. I don't understand what part of my code is wrong, but it should be about string manipulation. The SplitStr splits string by another string (strtok does it by character).
#define SplitCount 20
TCHAR** SplitStr(TCHAR* pstr, TCHAR *psplitby)
{
if (pstr == NULL || psplitby == NULL)
return NULL;
TCHAR** res = malloc(SplitCount * sizeof(TCHAR*));
int i = 0, j = 0, c = 0;
TCHAR* splitby = _tcsdup(psplitby); // I need to duplicate here
int len = _tcslen(splitby);
TCHAR* str = _tcsdup(pstr); // and here
int strlen1 = _tcslen(str);
while (i < MAXSTR - strlen1) {
if (i + len < strlen1 && _tcsncmp(splitby, &str[i], len) == 0)
{
res[c] = malloc(MAXSTR * sizeof(TCHAR*));
if (res[c] == NULL)
break;
_tcsncpy_s(res[c], MAXSTR, &str[j], i-j);
i += len;
j = i;
c++;
i--;
}
i++;
}
res[c] = malloc(MAXSTR * sizeof(TCHAR*));
if (res[c] != NULL)
{
_tcsncpy_s(res[c], MAXSTR, &str[j], strlen1 - j);
c++;
}
res[c] = _tcsdup(_T("END"));
return res;
}
TCHAR* StrToLower(TCHAR* Str)
{
int i = 0;
TCHAR * tstr = malloc(MAXSTR * sizeof(TCHAR));
ZeroMemory(tstr, MAXSTR * sizeof(TCHAR));
if (tstr != NULL)
{
_tcsset_s(tstr, MAXSTR, _T('\0'));
for (; i < MAXSTR; i++)
{
tstr[i] = _totlower(Str[i]);
}
}
return tstr;
}
int SelectFromTable(TCHAR* Table, FIELDS fields[], TCHAR* Where);
int execute_sentence(TCHAR* psentence)
{
TCHAR * sentence = StrToLower(psentence);
StrTrim(sentence, _T(" "));
TCHAR* dlimiter = _T("?");
if (_tcsncmp(_T("select"), sentence, _tcslen(_T("select"))) == 0)
{
TCHAR ** split = SplitStr(sentence, _T("where"));
TCHAR* select = split[0];
StrTrim(select, _T(" "));
TCHAR* where = split[1];
StrTrim(where, _T(" "));
//_putts(where); // here value is OK
TCHAR ** split2 = SplitStr(select, _T("from"));
TCHAR * fields = split2[0] + _tcslen(_T("select"));
TCHAR * table = split2[1];
StrTrim(table, _T(" "));
_putts(where); // here value is distorted now if I don't use _tcsdup above
TCHAR ** split3 = SplitStr(fields, dlimiter);
TCHAR* thefield = split3[0];
StrTrim(thefield, _T(" "));
FIELDS fields_arr[Field_Count];
int c_field_pos = 0, i = 1;
while (_tcscmp(thefield, _T("END")) != 0)
{
StrTrim(thefield, _T(" "));
c_field_pos = 0;
if (thefield != NULL)
{
for (int i = 0; i < Field_Count; i++)
{
if (_tcsncmp(thefield, table_columns[i], _tcslen(table_columns[i])) == 0) {
fields_arr[c_field_pos] = (FIELDS)i;
c_field_pos++;
break;
}
}
}
thefield = split3[i];
i++;
}
fields_arr[c_field_pos] = F_END;
SelectFromTable(table, fields_arr, where);
}
return 0;
}
I never expected the need to duplicate, I even used a pointer and kept it intact, still problem exists..

find the line which causes the segmentation fault, which I couldn't find

Currently I am writing a LZ77 algorithm. When I try to run my code, for some reason I get the ZSH segmentation fault. I've searched some topics but I couldn't find where to fix my code for this.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
/*#define pencereBoyutu 60
#define bufferBoyutu 40*/
typedef enum { false, true } bool;
// ============================================================================
int ortakBul(unsigned char window[], unsigned char str[], int strLen) {
int j, k, yer = -1;
int pencereBoyutu = 60;
for (int i = 0; i <= pencereBoyutu - strLen; i++) {
yer = k = i;
for (j = 0; j < strLen; j++) {
if (str[j] == window[k])
k++;
else
break;
}
if (j == strLen)
return yer;
}
return -1;
}
// ============================================================================
int compress(char* inputPath) {
FILE *fileInput;
FILE *fileOutput;
bool last = false;
int girisUzunlugu = 0;
int cikisUzunlugu = 0;
int setSonu = 0;
int yer = -1;
int i, size, shift, c_in;
size_t bytesRead = (size_t) -1;
int arrayBoyutu = 100;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
unsigned char c;
unsigned char array[arrayBoyutu];
unsigned char window[pencereBoyutu];
unsigned char buffer[bufferBoyutu];
unsigned char bufferYukle[bufferBoyutu];
unsigned char str[bufferBoyutu];
// input out açmak
char path[30] = "";
strcat(path, inputPath);
fileInput = fopen(path, "rb");
fileOutput = fopen("output/output.lz77", "wb");
// mümkün değilse error ver
if (!fileInput) {
fprintf(stderr, "fileInput acilamiyor. %s", inputPath);
return 0;
}
// fileinput uzunluğunu çek
fseek(fileInput, 0, SEEK_END);
girisUzunlugu = ftell(fileInput);
fseek(fileInput, 0, SEEK_SET);
fprintf(stdout, "Giris dosyasi boyutu: %d byte", girisUzunlugu);
// dosya boşsa hata ver
if (girisUzunlugu == 0)
return 3;
// eğer dosya boyutu arrayboyutundan düşükse hata ver
if (girisUzunlugu < arrayBoyutu)
return 2;
// arrayı byte olarak oku
fread(array, 1, arrayBoyutu, fileInput);
fwrite(array, 1, pencereBoyutu, fileOutput);
// LZ77 mantığı
while (true) {
if ((c_in = fgetc(fileInput)) == EOF)
last = true;
else
c = (unsigned char) c_in;
for (int k = 0; k < pencereBoyutu; k++)
window[k] = array[k];
for (int k = pencereBoyutu, j = 0; k < arrayBoyutu; k++, j++) {
buffer[j] = array[k];
str[j] = array[k];
}
// en uzun ortak kelimeyi bulmak
if (setSonu != 0) {
size = bufferBoyutu - setSonu;
if (setSonu == bufferBoyutu)
break;
}
else {
size = bufferBoyutu;
}
yer = -1;
for (i = size; i > 0; i--) {
yer = ortakBul(window, str, i);
if (yer != -1)
break;
}
// hiç ortak bulunmaması halinde
if (yer == -1) {
fputc(255, fileOutput);
fputc(buffer[0], fileOutput);
shift = 1;
}
// ortak bulunması halinde
else {
fputc(pencereBoyutu - yer, fileOutput);
fputc(i, fileOutput);
if (i == bufferBoyutu) {
shift = bufferBoyutu + 1;
if (!last)
fputc(c, fileOutput);
else
setSonu = 1;
}
else {
if (i + setSonu != bufferBoyutu)
fputc(buffer[i], fileOutput);
else
break;
shift = i + 1;
}
}
// Shift buffer
for (int j = 0; j < arrayBoyutu - shift; j++)
array[j] = array[j + shift];
if (!last)
array[arrayBoyutu - shift] = c;
if (shift == 1 && last)
setSonu++;
if (shift != 1) {
// yeni bitler oku
bytesRead = fread(bufferYukle, 1, (size_t) shift - 1, fileInput);
// yeni bitleri arraya yükle
for (int k = 0, l = arrayBoyutu - shift + 1; k < shift - 1; k++, l++)
array[l] = bufferYukle[k];
if (last) {
setSonu += shift;
continue;
}
if (bytesRead < shift - 1)
setSonu = shift - 1 - bytesRead;
}
}
// fileoutput uzunluğunu çek
fseek(fileOutput, 0, SEEK_END);
cikisUzunlugu = ftell(fileOutput);
fseek(fileOutput, 0, SEEK_SET);
fprintf(stdout, "\nCikis dosya boyutu: %d byte\n", cikisUzunlugu);
// I/O dosyaları kapanması
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
// Decompress
int decompress() {
FILE *fileInput;
FILE *fileOutput;
int shift, denge, ortak, c_in;
bool done = false;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
int arrayBoyutu = pencereBoyutu + bufferBoyutu;
unsigned char c;
unsigned char window[pencereBoyutu];
unsigned char writeBuffer[pencereBoyutu];
unsigned char readBuffer[2];
// i/o dosyalarin acilmasi
fileInput = fopen("output/output.lz77", "rb");
fileOutput = fopen("output/file", "wb");
if (!fileInput) {
fprintf(stderr, "fileInput açılamıyor. %s", "output.lz77");
return 0;
}
fread(window, 1, pencereBoyutu, fileInput);
fwrite(window, 1, pencereBoyutu, fileOutput);
// decompress mantığı
while (true) {
size_t bytesRead = fread(readBuffer, 1, 2, fileInput);
if (bytesRead >= 2) {
denge = (int) readBuffer[0];
ortak = (int) readBuffer[1];
if (denge == 255) {
denge = 0;
c = (unsigned char) ortak;
ortak = 0;
shift = ortak + 1;
}
else {
shift = ortak + 1;
c_in = fgetc(fileInput);
if (c_in == EOF)
done = true;
else
c = (unsigned char) c_in;
}
for (int i = 0, j = pencereBoyutu - denge; i < ortak; i++, j++)
writeBuffer[i] = window[j];
fwrite(writeBuffer, 1, (size_t) ortak, fileOutput);
if (!done)
fputc(c, fileOutput);
// Shift window
for (int i = 0; i < pencereBoyutu - shift; i++)
window[i] = window[i + shift];
for (int i = 0, j = pencereBoyutu - shift; i < ortak; i++, j++)
window[j] = writeBuffer[i];
window[pencereBoyutu - 1] = c;
}
else {
break;
}
}
// dosyaları kapat
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
int main(int argc, char* argv[]) {
clock_t begin = clock();
if (argc < 2) {
printf("2 argüman gerekiyor: [-c|-d] [dosya_yolu]");
} else {
// decompress
if (strcmp(argv[1], "-d") == 0) {
int result = decompress();
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
}
}
// compress
else if (strcmp(argv[1], "-c") == 0) {
int result = compress(argv[2]);
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI\n");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
} else if (result == 2) {
fprintf(stderr, "\nDosya cok kucuk.\n");
} else if (result == 3) {
fprintf(stderr, "\nDosya bos.\n");
}
} else {
printf("Gecersiz argumanlar.");
}
}
// calistirma zamanını bastırmak
clock_t end = clock();
printf("\n\nCalistirma zamani: ");
printf("%f", ((double) (end - begin) / CLOCKS_PER_SEC));
printf(" [saniye]");
return 0;
}
// ============================================================================
After compiling you have to give arguments for running:
./lz77 -c input.txt
when I try to run my application with the input above which has 100 characters in it, it gives me segmentation fault. I couldn't find any reason after done some research about it. I'll be so happy if anyone can help.

Cannot understand why program crashes after a couple iterations of while loop?

I am writing the following program to parse the text file (attached) but it keeps crashing after couple of iterations of while loop or it seems that the buffer storing file contents is corrupted somehow?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
char * pick_question(char *, char, int);
char * print_answer(char *, char, int);
int no_of_questions(char*, char);
void clear();
int debug = 0;
int main(int argc, char* argv[])
{
system("cmd /c chcp 1252");
// system("cmd /c chcp 65001");
if (argc < 2)
{
perror("Please enter a filename!\n");
exit(0);
}
if (argc > 2)
{
debug = atoi(argv[2]);
}
char const* const fileName = argv[1];
FILE* file = fopen(fileName, "r");
if (!file)
{
perror("Unable to read file!\n");
exit(0);
}
else
{
if (debug == 1)
{
printf("File opened successfully\n");
}
}
static char *buffer;
int fileSz;
fseek(file, 0, SEEK_END);
fileSz = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = (char*) malloc((fileSz + 1) * sizeof(char));
if (!buffer)
{
perror("Unable to allocate buffer!");
exit(0);
}
fread(buffer, sizeof(char), fileSz, file);
while (1)
{
time_t t;
srand((unsigned) time(&t));
int sub = rand() % 5 + 1;
char del;
switch (sub)
{
case 1:
del = 'A';
break;
case 2:
del = 'B';
break;
case 3:
del = 'C';
break;
case 4:
del = 'D';
break;
case 5:
del = 'E';
}
int nrOfQues = no_of_questions(buffer, del);
if (nrOfQues == 0)
{
perror("main(): no_of_questions() returned 0. Unsupported text structure in file or incorrect file encoding!");
fclose(file);
exit(0);
}
int qNo = rand() % nrOfQues + 1;
char *ques = pick_question(buffer, del, qNo);
if (ques)
{
printf("\n\n");
puts(ques);
printf("\n\n");
}
else
{
perror("main(): pick_question() returned NULL. Unsupported text structure in file!");
fclose(file);
exit(0);
}
printf("\n\n");
printf("Do you want to see the answer(y/n)?");
char ans, repeat;
scanf("%c", &ans);
if ( ans == 'Y' || ans == 'y')
{
char *ans = print_answer(buffer, del, qNo);
if (ans)
{
printf("\n\n");
puts(ans);
printf("\n\n");
}
else
{
printf("\n\n");
perror("main(): print_answer() returned NULL. Unsupported text structure in file!");
fclose(file);
exit(0);
}
}
printf("Do you want to try more questions (y/n)?");
clear();
scanf("%c", &repeat);
if (repeat == 'N' || repeat == 'n')
{
break;
}
clear();
}
printf("\n\n");
printf("******** Thank you for using TULE Master! ********");
printf("\n\n");
fclose(file);
return 0;
}
char * pick_question(char * buffer, char sub, int qNo)
{
char tmpBuff[20];
char tmpBuff2[20];
const char * searchStr = "FRÅGA";
const char * searchStr2 = "A 1 SVAR:";
const char * searchStr3 = "*****************************************";
char *pStr, *currPos, *nStr, *tmpStr, *tmpStr2;
currPos = buffer;
int count = snprintf(tmpBuff, 20, "FRÅGA %c %d", sub, qNo);
if (count >= 0 || count < 20)
{
if (debug)
{
printf("tmpBuff is %s\n", tmpBuff);
}
currPos = strstr(currPos, tmpBuff);
if (currPos)
{
pStr = currPos;
nStr = currPos + 1;
nStr = strstr(nStr, searchStr);
if (!nStr)
{
nStr = currPos;
nStr = strstr(nStr, searchStr2);
if (!nStr)
{
printf("pick_qestion(): nStr is NULL. Unsupported "
"text structure");
return NULL;
}
}
// Check if it is a scenario based question
count = snprintf(tmpBuff2, 20, "FRÅGA %c %d", sub, qNo-1);
if (count >= 0 || count < 20)
{
tmpStr = strstr(buffer, tmpBuff2);
tmpStr2 = strstr(tmpStr, searchStr3);
if (tmpStr < tmpStr2 && tmpStr2 < pStr)
{
pStr = tmpStr2;
}
}
int qLen = nStr - pStr;
char *ques = malloc(sizeof(char) * (qLen+1));
snprintf(ques,qLen,"%s", pStr);
return ques;
}
else
{
printf("pick_qestion(): string \"FRÅGA\" not found in file!");
return NULL;
}
}
printf("pick_qestion(): snprintf was not successful!");
return NULL;
}
char * print_answer(char * buffer, char sub, int qNo)
{
char tmpBuff[20];
char *pStr, *currPos, *nStr;
int count = snprintf(tmpBuff, 20, "%c %d SVAR:", sub, qNo);
if (count >= 0 || count < 20)
{
currPos = strstr(buffer, tmpBuff);
if (!currPos)
{
printf("print_answer(): string \"SVAR\" not found in file!");
}
pStr = currPos;
nStr = currPos + 1;
char tmpBuff2[20];
int count = snprintf(tmpBuff2, 20, "%c %d SVAR:", sub, qNo+1);
if (count < 0 || count >= 20)
{
printf("print_answer(): snprint was not successful!");
return NULL;
}
nStr = strstr(nStr, tmpBuff2);
if (!nStr)
{
nStr = buffer + strlen(buffer);
}
int ansLen = nStr - pStr;
char *ans = malloc(sizeof(char) * (ansLen+1));
snprintf(ans, ansLen, "%s", pStr);
return ans;
}
printf("print_answer(): snprint was not successful!");
return NULL;
}
int no_of_questions(char *buffer, char sub)
{
char tmpBuff[20];
char *currPos, *pStr;
int count = snprintf(tmpBuff, 20, "FRÅGA %c", sub);
if (count >= 0 || count < 20)
{
if (debug)
{
printf("tmpBuff is %s\n", tmpBuff);
}
currPos = strstr(buffer, tmpBuff);
while (currPos != NULL)
{
pStr = currPos;
currPos = currPos + 1;
currPos = strstr(currPos, tmpBuff);
}
if (pStr != buffer)
{
pStr += 9;
char tmpBuff2[20];
memcpy(tmpBuff2, pStr, 2);
if (debug)
{
printf("No. of questions for %c DEL is are %d\n", sub,
atoi(tmpBuff2));
}
return atoi(tmpBuff2);
}
return 0;
}
return 0;
}
void clear()
{
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
}
This is the file that is given as input to the program:
Link

Segmentation fault using fgets in C

My code is not working and it is when I call fgets in the commandSplit function. I figured this out by printing "Am I here" in multiple places and find that the error at fgets it seems. I may be wrong, but I am pretty sure. I get a segmentation fault and I can not figure out why. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAX_CHARACTERS 512
int Execute(char *a[], int t[], int num) {
int exitShell = 0;
int l = 0;
for (int i = 0; i < num; i++) {
int status;
if (strcmp(a[0], "quit") == 0) {
exitShell = 1;
}
if (t[i] && ((strcmp(a[l], "quit") == 0))) {
exitShell = 1;
}
char *holder[t[i]+1];
for (int j = 0; j < t[i]; j++) {
holder[j] = a[l];
l++;
}
holder[t[i]] = NULL;
pid_t p = fork();
pid_t waiting;
if (p == 0) {
execvp(holder[0], holder);
fprintf(stderr, "Child process could not execvp!\n");
exit(1);
} else {
if (p < 0) {
fprintf(stderr, "Fork FAILED!\n");
} else {
waiting = wait(&status);
printf("Child %d exit with status %d\n", waiting, status);
}
}
for (int g = 0; g < t[i]; g++) {
a[g] = NULL;
}
}
for (int i = 0; i < num; i++) {
t[i] = 0;
}
return exitShell;
}
int commandSplit(char *c, FILE *f, char *a[], int t[]) {
int count = 0;
int emptyfile = 1;
int stat = 0;
int total1 = 0;
char *temp[MAX_CHARACTERS];
if (c != NULL) {
char *readCommands = strtok(c, ";");
while (readCommands != NULL) {
temp[count] = readCommands;
count++;
readCommands = strtok(NULL, ";");
}
for (int i = 0; i < count; i++) {
char *read = strtok(temp[i], " ");
int track1 = 0;
while (read != NULL) {
a[total1] = read;
track1++;
total1++;
read = strtok(NULL, " ");
}
t[i] = track1;
}
stat = Execute(a, t, count);
} else {
char *buildCommands = "";
printf("Am I here???\n");
while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
printf("Am I here???\n");
emptyfile = 0;
commandSplit(buildCommands, NULL, a, t);
stat = Execute(a, t, count);
}
if (emptyfile) {
printf("File is empty!\n");
stat = 1;
}
}
printf("Am I here???\n");
return stat;
}
int main(int argc, char *argv[]) {
int exitProgram = 0;
FILE *fileRead = NULL;
if (argc == 2) {
fileRead = fopen(argv[1], "r");
if (fileRead == NULL) {
printf("No such file exists\n");
exitProgram = 1;
}
}
if (argc > 2) {
printf("Incorrect batch mode call\n");
exitProgram = 1;
}
char *args[MAX_CHARACTERS];
int tracker[MAX_CHARACTERS];
while (!exitProgram) {
if (argc == 1) {
char *commands = (char *)(malloc(MAX_CHARACTERS * sizeof(char)));
printf("tinyshell>");
if (fgets(commands, MAX_CHARACTERS, stdin) == NULL) {
exitProgram = 1;
printf("\n");
}
int len;
len = strlen(commands);
if (len > 0 && commands[len-1] == '\n') {
commands[len-1] = '\0';
}
if (len > MAX_CHARACTERS) {
printf("TOO MANY CHARACTERS - MAX: 512\n");
continue;
}
if (strlen(commands) == 0)
continue;
exitProgram = commandSplit(commands, NULL, args, tracker);
} else {
exitProgram = commandSplit(NULL, fileRead, args, tracker);
}
}
fclose(fileRead);
return 0;
}
As commented #Jean-François Fabre , buildCommands points to insufficient space and potential const space;
char *buildCommands = "";
...
// bad code
while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
Allocate space with an array or malloc()
char buildCommands[MAX_CHARACTERS];
...
while ((fgets(buildCommands, sizeof buildCommands, f) != NULL) && !stat) {
...
}
// or
char *buildCommands = malloc(MAX_CHARACTERS);
assert(buildCommands);
...
while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
...
}
...
free(buildCommands);

char array input with space

my program works fine if i give hard code value to char *w="ls -l" but i am trying to take input form user not working help my code:: using input error occur
i don't understand the concept of fgets using fgets its gives the garbig value to execv
#include<stdio.h>
#include<sys/wait.h>
#include<stdbool.h>
void func(char **arr, char *w)
{
int i = 0, j = 0, k = 0;
char temp[100];
for (i = 0; i < 100; i++)
{
if (w[i] == '')
{
arr[k] = temp;
arr[k+1] = NULL;
break;
}
if (w[i] == ' ')
{
arr[k] = temp;
k++;
j = 0;
}
else
{
temp[j] = w[i];
j++;
}
}
}
int main()
{
char *n = "/bin/ls";
char *arr[10] = {''};
char p[100] = {''};
char *w = "ls -l";
int i = 0;
//printf("bilal-hassan-qadri $ >>");
//fgets(p, 100, stdin);
arr[2] = NULL;
bool found = false;
for (i = 0; i < sizeof(w); i++)
{
if (w[i] == ' ')
{
found=true;
func(arr,w);
break;
}
}
if (!found)
arr[0] = w;
int status;
int id = fork();
if (id == 0)
{
if (execv(n,arr) < 0)
{
printf("invalid commandn");
}
else
{
printf("ninvalid command");
}
}
else
{
wait(&status);
}
}
In the function func, You have to copy the string to elements of arr
instead of just passing the address of temp, which will vanish on leaving the function.
You can use strdup instead of copy_string if your system supports it.
You have to terminate the string in temp before copying it.
Empty string constant '' seems invalid. You shouldn't use it.
fgets stores new-line character \n if it exists. Check for it and remove if it isn't wanted.
Fixed code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<stdbool.h>
char *copy_string(const char *str) {
char *s = malloc(strlen(str) + 1);
if (s) strcpy(s, str); else {perror("malloc"); exit(1);}
return s;
}
void func(char **arr, char *w)
{
int i = 0, j = 0, k = 0;
char temp[100];
for (i = 0; i < 100; i++)
{
if (w[i] == '\0' || w[i] == '\n')
{
temp[j] = '\0';
arr[k] = copy_string(temp);
arr[k+1] = NULL;
break;
}
if (w[i] == ' ')
{
temp[j] = '\0';
arr[k] = copy_string(temp);
k++;
j = 0;
}
else
{
temp[j] = w[i];
j++;
}
}
}
int main(void)
{
char *n = "/bin/ls";
char *arr[10] = {NULL};
char p[100] = {0};
char *w = "ls -l";
int i = 0;
//printf("bilal-hassan-qadri $ >>");
fgets(p, 100, stdin);
w = p;
arr[2] = NULL;
bool found = false;
for (i = 0; w[i] != '\0'; i++)
{
if (w[i] == ' ')
{
found=true;
func(arr,w);
break;
}
}
if (!found)
arr[0] = w;
int status;
int id = fork();
if (id == 0)
{
if (execv(n,arr) < 0)
{
printf("invalid commandn");
}
else
{
printf("ninvalid command");
}
}
else
{
wait(&status);
for (i = 0; arr[i] != NULL; i++) free(arr[i]);
}
return 0;
}

Resources