I am trying to read a file. I want to read each line from the file and check if there are any spelling error in that line.
For that I have added condition that data from file will store in buffer until it gets a new line characher '\n'. And after getting this line I want to empty the buffer and re insert the values in that.
Code I am using for the same is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define W_COUNT 23800
#define MAX_LEN 100
char *dict[W_COUNT];
char buffer[MAX_LEN];
int num_words; //No of Words
char *statement[W_COUNT];
char buffer1[MAX_LEN];
void read_dictionary();
void file_read(char *);
void spell_check();
int word_search(char*);
int main(int argc, char*argv[]){
int i;
if(argc < 2){
printf("Expected Filename.\n");
exit(0);
}
read_dictionary();
file_read(argv[1]);
// spell_check();
}
void read_dictionary(){
FILE *fd;
int i = 0;
fd = fopen("dictionary", "r");
while ( fscanf(fd,"%s",buffer) != EOF)
dict[i++] = strdup(buffer);
num_words = i;
fclose(fd);
}
void file_read(char *filename){
FILE *fd;
int i = 0;
char c;
fd = fopen(filename,"r");
/*while ( fscanf(fd,"%s",buffer1) != EOF)
{
word[i++] = strdup(buffer1);
printf("File : %s\n", buffer1);
}*/
while ( ( c = fgetc(fd)) != EOF )
{
buffer1[i++] = tolower(c);
if ( c == '\n')
{
//printf("New Line\n");
spell_check();
buffer1[i] = 0;
}
//buffer1[i] = 0;
}
printf("Statement : %s\n", buffer1);
fclose(fd);
}
void spell_check(){
char *str;
str = strtok(buffer1," .?,!-");
while( str != NULL){
if(!word_search(str))
printf("%s Not found.\n",str);
str = strtok(0," .?,!-");
}
}
int word_search(char *word){
int high, low, mid;
high = num_words - 1;
low = 0;
int found = 0;
while (found == 0){
mid = (low + high) / 2;
if(strcmp(word, dict[mid]) == 0)
return 1;
else if(strcmp(word,dict[mid]) < 0)
high = mid - 1;
else
low = mid + 1;
if ( low > high)
return 0;
}
}
Any suggestions will be appreciated.
Thank you in advance.
while ( ( c = fgetc(fd)) != EOF )
{
buffer1[i++] = tolower(c);
if ( c == '\n')
{
//printf("New Line\n");
spell_check();
i = 0;
buffer1[i] = 0;
}
//buffer1[i] = 0;
}
For each line reading you have to assign the 0 to the i. After that you have to assign the null to the 0th position in the buffer.
You can try the above code for loop it will work.
Related
I am doing the Advent of Code, and I am trying to do it all in C. I am currently on day three, and I kind of solved it, but as the title says it behaves very strangely in my IDE CLion. Here is the objective.
I would very much like to know why it is not running properly, and finding out why appears to be beyond my capability.
This is my code:
//
// Created by gusta on 2022-12-06.
//
#include "aocio.h"
#include <string.h>
int cexists(char* cp, char c, int length);
char getDuplicate(char* line);
int main() {
FILE* fptr = openFile("../Inputs/day3.txt");
char* line;
while (readLine(fptr, &line)) {
char c = getDuplicate(line);
putchar(c);
}
return 0;
}
char getDuplicate(char* line) { // Returnerar STRING_END om ingen fanns
unsigned int length = strlen(line);
char letters[length/2];
char* cp = &letters[0];
for (int i = 0; i < length/2; i++) {
letters[i] = ' ';
}
for (int index = 0; line[index] != STRING_END; index++) {
if (index < length/2) {
int i_char = cexists(letters, line[index], length/2);
if (i_char == -1) {
*cp = line[index];
cp++;
}
}
else {
if (cexists(letters, line[index], length/2) != -1) {
return line[index];
}
}
}
}
int cexists(char* cp, char c, int length) {
for (int i = 0; i < length; i++) {
if (cp[i] == c) {
return i;
}
}
return -1;
}
Here is aocoi.h (advent of code input output.h):
//
// Created by gusta on 2022-12-01.
//
#ifndef ADVENTOFCODE_AOCIO_H
#define ADVENTOFCODE_AOCIO_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define SIGN_ASCII 45
#define TRUE 1
#define FALSE 0
#endif //ADVENTOFCODE_AOCIO_H
#define STRING_END '\0'
#define NUMBERS_ASCII 48
char* prompt(const char* question) {
printf(question);
char* string = malloc(1);
int curChar = 0, index = 0;
while (curChar != '\n') {
curChar = getchar();
if (curChar == '\n'){
string[index] = STRING_END;
}
else{
if (index > 0) {
string = (char*) realloc(string, index+1);
}
string[index] = curChar;
}
index++;
}
return string;
}
FILE* openFile(const char* fileName) {
FILE *fptr;
fptr = fopen(fileName, "r");
if (fptr == NULL) {
printf("Big fat file error!!\n");
fclose(fptr);
getchar();
exit(-1);
}
return fptr;
}
char readLine(FILE* fptr, char** line) {
int index = 0, end = 0;
char* string = (char *) malloc(1);
char curChar;
do {
end = fscanf(fptr, "%c", &curChar);
if (end == EOF) {
string[index] = STRING_END;
fclose(fptr);
*line = string;
return FALSE;
}
if (curChar == '\n') {
string[index] = STRING_END;
*line = string;
return TRUE;
}
else {
if (index > 0) {
string = (char *) realloc(string, index + 1);
}
string[index] = curChar;
index++;
}
} while (end != EOF);
}
int parseToInt(char* string) {
int numberLength = 0, number = 0;
int sign = FALSE;
for (int index = 0; string[index] != STRING_END; index++) {
numberLength++;
}
for (int index = numberLength-1; index >= 0; index--) {
char curChar = string[index];
if (index == 0 && curChar - SIGN_ASCII == 0) {
sign = TRUE;
continue;
}
if (curChar - NUMBERS_ASCII >= 0 && curChar - NUMBERS_ASCII <= 9) {
int num = (int) (curChar - NUMBERS_ASCII);
num *= (int)(pow(10, numberLength-index-1));
number += num;
}
else {
printf("Felaktig inmatning. parseInt kan bara ta in tal"); // Invalid input. parseInt can only take in numbers
getchar();
exit(-1);
}
}
if (sign == TRUE) {
number *= -1;
}
return number;
}
Through searching the web I found that the error code should mean stack overflow (ha!) or something like that, but I cannot for the life of me find any place in my code where that could occur. All pointers and stuff should be automatically freed - is there something I have missed?
In readLine():
if (index > 0) {
string = (char *) realloc(string, index + 1);
}
string[index] = curChar;
After this section, the buffer has size index+1, therefore string[index] is the last element you can write to. Afterwards, you do
index++;
Now, writing to string[index] is out of bounds, resulting in a buffer overflow. This is what happens when an EOF or EOL is detected.
this is my first Question here so im grateful for every kind of Help.
Im trying to get the length of the longest Line in a File, so i can later calloc it and read the whole File in. My first attempt was Dynamic, but it didnt work.
My Code till now is:
FILE *inputData;
inputData = fopen("input.txt", "r");
char *input = NULL;
int longestLinelength = 0;
while(fscanf(inputData,"%[^\n]", input) != EOF) {
if(longestLineLength<strlen(input)){
longestLineLength=strlen(input);
}
}
fclose()
This code unfortunetly leads to a memory access error.
size_t longestLine(FILE *fi)
{
size_t largest = 0, current = 0;
int ch;
if(fi)
{
while((ch = fgetc(fi)) != EOF)
{
if(ch == '\n')
{
if(current > largest) largest = current;
current = 0;
}
else
{
current++;
}
}
if(current > largest) largest = current;
}
return largest;
}
I think the problem is not with realloc, but with a misunderstanding of how things work.
It would be best to read carefully what scanf does. And how pointers work.
input is a NULL pointer and you want to write to it, this causes a crash in the application. scanf needs allocated memory to write to, it does not allocate it itself. Generally I would suggest to use fgets instead of scanf as it is better to handle. The formating options of scanf can be done after you read it with fgets.
Probably this help this is based on the book The C Programming Language.
First we need a main function to get the lines in the file
int get_file_line(char line[], int maxline, FILE *fptr) {
int ch, i;
for (i = 0; i < (maxline - 1) && ((ch = getc(fptr)) != EOF) && (ch != '\n'); ++i) {
line[i] = ch;
}
if (ch == '\n') {
line[i] = ch;
++i;
}
line[i] = '\0';
return i;
}
Then we will store the data into a new array of chars
void copy(char to[], char from[]) {
int i = 0;
while (from[i] != '\0') {
to[i] = from[i];
i++;
}
}
And finally in the main function we gonna open the file and use the previous functions
FILE *ptr;
const char *file_name = "your_file.txt";
ptr = fopen(file_name, "r");
while ((len = get_file_line(line, MAXLINE, ptr)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
fclose(ptr);
if (max > 0) {
printf("longest: %s\n", longest);
printf("len : %d\n", max);
}
All together
#include <stdio.h>
#define MAXLINE 1000
int get_file_line(char line[], int maxline, FILE *fptr) {
int ch, i;
for (i = 0; i < (maxline - 1) && ((ch = getc(fptr)) != EOF) && (ch != '\n'); ++i) {
line[i] = ch;
}
if (ch == '\n') {
line[i] = ch;
++i;
}
line[i] = '\0';
return i;
}
void copy(char to[], char from[]) {
int i = 0;
while (from[i] != '\0') {
to[i] = from[i];
i++;
}
}
int main() {
int len, max = 0;
char line[MAXLINE];
char longest[MAXLINE];
FILE *ptr;
const char *file_name = "your_file.txt";
ptr = fopen(file_name, "r");
while ((len = get_file_line(line, MAXLINE, ptr)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
fclose(ptr);
if (max > 0) {
printf("longest: %s\n", longest);
printf("len : %d\n", max);
}
return 0;
}
I hope this was helpful
#include <stdio.h>
#include <string.h>
#define MAX_LINE_LENGTH 4096
static void process_file(char *filename);
int main(int argc, char **argv) {
int q;
if(argc <= 1) {
printf("Usage: %s <files>\n", argv[0]);
return 1;
}
for(q = 1; q < argc; q++) {
process_file(argv[q]);
}
return 0;
}
void process_file(char *filename) {
char buf[MAX_LINE_LENGTH] = {0};
FILE *file;
char line_val[MAX_LINE_LENGTH] = {0};
int line_len = -1;
int line_num = -1;
int cur_line = 1;
file = fopen(filename, "r");
if(file == NULL) {
return;
}
while(fgets(buf, MAX_LINE_LENGTH, file) != NULL) {
int len_tmp = strlen(buf) - 1;
if(buf[len_tmp] == '\n')
buf[len_tmp] = '\0';
if(line_len < len_tmp) {
strncpy(line_val, buf, len_tmp + 1);
line_len = len_tmp;
line_num = cur_line;
}
cur_line++;
/*printf("%s", buf);*/
}
fclose(file);
if(line_num < 1) {
return;
}
printf("%d:%s:%d:%s\n", line_len, filename, line_num, line_val);
}
I've been developing a guessing game in which the goal is to guess the character selected by the user among specific characters, anyway, my first and only idea is to create an array with the questions to be asked, and each question has its options like in the code below I'm a newbie in C language so that I there are several things which I'm not sure how to handle. In short, I'd like to know how can I loop over the array showing to the user the questions with its questions to be answered? Here's the code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ROW 500
#define LINE 200
//Read file and append to an array buffer
char *characters(){
char *source = NULL;
FILE *fp = fopen("file.txt", "r");
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
long bufsize = ftell(fp);
if (bufsize == -1) { /* Error */ }
/* Allocate our buffer to that size. */
source = malloc(sizeof(char) * (bufsize + 1));
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { /* Error */ }
/* Read the entire file into memory. */
size_t newLen = fread(source, sizeof(char), bufsize, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
} else {
source[newLen++] = '\0'; /* Just to be safe. */
}
}
fclose(fp);
}
return source;
}
char *strndup(const char *s, size_t n) {
char *p;
size_t n1;
for (n1 = 0; n1 < n && s[n1] != '\0'; n1++)
continue;
p = malloc(n + 1);
if (p != NULL) {
memcpy(p, s, n1);
p[n1] = '\0';
}
return p;
}
// User input
char *input(){
char *value;
char buffer[10];
int j = 0;
while( j < 1 && fgets(buffer, 10, stdin) != NULL){
value = strndup(buffer, 10);
j++;
}
return value;
}
// Main function
int main (void)
{
char *questions[] = {
"Genre",{"male","female"},
"Hair", {"black","red","blond"},
"Cloths",{"dress","shirt","pants"},
"pet", {"dog","cat","pig"}
};
int asked[4] = {0};
char *answers[5];
char buffer[6];
srand(time(NULL));
for (int i = 0; i < 4; i++) {
int q = rand() % 4;
while (asked[q])
q = rand() % 4;
asked[q]++;
printf ("%s\n", questions[q]);
answers[i] = input();
}
for(int i = 0; i < 4; i++)
{
printf(" %s ",answers[i]);
}
return 0;
}
That's the file's structure I'll compare as long as I have all the answers from the user.
female,blond,vestido,pig,character b
male,black,shirt,pants,dog,character c
male,black,shirt,pants,cat,character d
female,blond,dress,cat,character A
male,red,shirt,pants,pig,character e
This question already has answers here:
C read file line by line
(17 answers)
Closed 5 years ago.
I am new to c programming. I'm writing a program that reads a text file and stores in each line in into a char*[] data structures. I know how to this with characters, but I don't know how to store each line? does it require a 2D array? thats the code I have but I get segmentation error. I'm just trying to print out I and j to check if it works.
Thank you
#include <stdio.h>
#define NUMBER_LINES 400
int main()
{
char lines[NUMBER_LINES][255];
FILE *fp = fopen("input.txt", "r");
if (fp == 0)
{
return 1;
}
char c;
int i ;
while (fscanf (fp, "%c", &c) == 1)
{
i = 0;
int j;
for (j=0; !(c=='\n'); j++){
lines[i][j] = c;
}
if (c == '\n'){
printf("%s%s\n", lines[i][j]);
i++;
}
}
return 0;
}
You could use a matrix:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMBER_LINES 100
int main(void)
{
int i = 0;
char lines[NUMBER_LINES][255];
FILE *fp = fopen("file.txt", "r");
if (fp == 0)
{
fprintf(stderr, "failed to open input.txt\n");
exit(1);
}
while (i < NUMBER_LINES && fgets(lines[i], sizeof(lines[0]), fp))
{
lines[i][strlen(lines[i])-1] = '\0';
printf("\n%s", lines[i]);
i = i + 1;
}
fclose(fp);
return 0;
}
The code :
#include "get_next_line.h"
int check_n(char *str)
{
int i;
i = 0;
while (str && str[i])
{
if (str[i] == '\n')
return (i);
i++;
}
return (-1);
}
char *my_strdup_gnl(char *src)
{
int i;
char *str;
int ret;
i = 0;
if ((ret = check_n(src)) == -1)
return (NULL);
if ((str = malloc(sizeof(char) * ret + 1)) == NULL)
return (NULL);
while (i < ret)
{
str[i] = src[i];
i++;
}
str[i] = '\0';
return (str);
}
char *boucle_gnl(char *line, char *buff, int ret, int i)
{
strcat(line, buff);
i = 0;
while (buff[ret + 1] != '\0')
{
buff[i] = buff[ret + 1];
i++;
ret++;
}
buff[ret] = 0;
while (i < READ_SIZE + 1)
{
buff[i] = '\0';
i++;
}
return (line);
}
char *boucle_else_gnl(char *line, char *buff, int ret, int fd)
{
int i;
i = 0;
line = =strcpy(line, buff);
while (i < READ_SIZE + 1)
{
buff[i] = '\0';
i++;
}
if ((ret = read(fd, buff, READ_SIZE)) <= 0)
return (NULL);
return (line);
}
char *get_next_line(const int fd)
{
static char buff[READ_SIZE + 1] = {'\0'};
char *line;
int ret;
int i;
int tmp;
i = 0;
tmp = 0;
line = NULL;
if (!buff[0] && (ret = read(fd, buff, READ_SIZE)) <= 0)
return (NULL);
while (tmp++ != -1)
{
if ((line = my_realloc(line, (tmp * READ_SIZE))) == NULL)
return (NULL);
if ((ret = check_n(buff)) != -1)
return (line = boucle_gnl(line, buff, ret, i), line);
else
{
if ((line = boucle_else_gnl(line, buff, ret, fd)) == NULL)
return (NULL);
}
}
return (NULL);
}
The "my_realloc function" :
char *my_realloc(char *buff, int nb)
{
char *buf2;
int i;
i = 0;
if ((buf2 = malloc(sizeof(char) * (strlen(buff) + nb + 1))) == NULL)
return (NULL);
if (buff == NULL)
{
buf2[0] = '\0';
return (buf2);
}
while (buff[i])
{
buf2[i] = buff[i];
i++;
}
buf2[i] = '\0';
return (buf2);
}
The "get_next_line.h" :
#ifndef GET_NEXT_LINE_H_
# define GET_NEXT_LINE_H_
#ifndef READ_SIZE
# define READ_SIZE 10000
#include <unistd.h>
#include <stdlib.h>
#endif /* !READ_SIZE */
#endif /* !GET_NEXT_LINE_H_ */
In matlab we can do it using the code :
a= csvread('filename.csv');
But using C programming i used the following code but it doesnt works please help :
int main(){
int i,j,temp,m1=0,n=0;
//CSV file reading
int ch;
FILE *fp;
fp = fopen("filename.csv","r"); // read mode
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(fp) ) != EOF )
{printf("%d",ch);}
fclose(fp);
return 0;
}
mat[i][j] = ch;
int m1 = i;
int n = j;
}
Please help !
Ok this hasn't been extensively tested but it should read a csv file that has integer values and store them in an (n x m) matrix.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
//CSV file reading
int rowMaxIndex,columnMaxIndex;
int **mat;
int *matc;
int i,j,idx;
char part[1024];
char *token;
FILE *fp;
fp = fopen("filename.csv","r"); // read mode
if(fp == NULL){
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
// count loop
rowMaxIndex = 0;
columnMaxIndex = 0;
while(fgets(part,1024,fp) != NULL){
token = NULL;
while((token = strtok((token == NULL)?part:NULL,",")) != NULL){
if(rowMaxIndex == 0){ // only want to increment column count on first loop
columnMaxIndex++;
}
for(idx = 0;idx<strlen(token);idx++){
if(token[idx] == '\n'){ // this assumes there will be a \n (LF) at the end of the line
rowMaxIndex++;
break;
}
}
}
}
// allocate the matrix
matc = malloc(rowMaxIndex*columnMaxIndex*sizeof(int));
mat = malloc(rowMaxIndex*sizeof(int*));
for(idx = 0;idx<rowMaxIndex;idx++){
mat[idx] = matc+idx*columnMaxIndex;
}
// rewind the file to the beginning
rewind(fp);
// read loop
i = j = 0;
while(fgets(part,1024,fp) != NULL){
token = NULL;
while((token = strtok((token == NULL)?part:NULL,",")) != NULL){
mat[i][j] = atoi(token);
j = (j+1)%columnMaxIndex;
}
i++;
}
fclose(fp);
return 0;
}