Read all lines from file to a array [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
How can I read multiple lines (approximately 5000 lines) from a text file and store all of them in a single string array?
i already have some of the code running smooth, but it doesn't work the way its supposed to. I only get the last line of the file stored in the array.
int main(){
int n;
char line[401];
char string[10000];
fr = fopen ("fila1b.txt", "rt");
while(fgets(line, 400, fr) != NULL){
strcat(string, line);
}
fclose(fr);
printf("%s\n", string );
}
EDIT: I updated the code with some changes. Now i'm using the strcat function to insert the contents of the line got by fgets to the original string array. It is working, apparently. But when i print the 'string', it only prints the first 300 lines and then it gives me Segmentation fault.

The usual way is to just slurp all the characters with read or fread:
#define MIN_CHUNK_SIZE (1024)
char *read_file(FILE *f) {
size_t n_read_total = 0;
size_t buf_size = MIN_CHUNK_SIZE + 1; // Allow space for nul terminator.
char *buf = safe_malloc(buf_size);
size_t n_avail;
do {
n_avail = buf_size - n_read_total - 1;
if (n_avail < MIN_CHUNK_SIZE) {
// Double the buffer size.
n_avail += buf_size;
buf_size += buf_size;
buf = safe_realloc(buf, buf_size);
}
size_t n_read = fread(buf + n_read_total, 1, n_avail, f);
n_read_total += n_read;
} while (n_read == n_avail);
buf[n_read_total] = '\0';
return safe_realloc(buf, n_read_total + 1);
}

Related

Storing a variable integer with a char Array in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I want to extract, edit and re-concatenate a string that contains an integer. How does this get done?
char str_test[] = "CAT ";
int count = 10;
//(1) something here to combine str_test and count stored in some variable
char str_new[] = ????;
//(2) something else here to extract the 10 and +1?
//such that if I print str_new, it gives me "CAT 11"
????
You can use sprintf to write a formatted number to a string, and you can use snprintf to find out how many characters are required.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Return a newly allocated string containing String followed by Number
converted to decimal. The caller is responsible for freeing the memory.
*/
static char *ConcatenateIntToString(const char *String, int Number)
{
// Get the number of non-null characters in String.
size_t Length = strlen(String);
/* Allocate space for:
the characters in String,
the characters needed to format Number with "%d", and
a terminating null byte.
*/
char *Result = malloc(
Length
+ snprintf(NULL, 0, "%d", Number)
+ 1);
// Test whether the allocation succeeded.
if (!Result)
{
fprintf(stderr, "Error, unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
// Copy the characters from String.
memcpy(Result, String, Length);
// Append the formatted number and a null terminator.
sprintf(Result + Length, "%d", Number);
// Return the new string.
return Result;
}
int main(void)
{
char *NewString = ConcatenateIntToString("CAT ", 11);
printf("The new string is %s.\n", NewString);
free(NewString);
}

C safe and proper way to get user input [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
Safe input is harder than I thought. I looked around and found this, but it is from 2011 and things might have changed since then.
I'm looking for something that can handle string input and single character input. For example:
Hello, what's your name?
My name is: _
Are you sure?
[Y] Yes, hello
[N] No, goodbye
_
Here is the way I'm doing it right now:
char input[16];
fgets(input, 16, stdin);
char input = getchar();
My problem has always been that the user may input arbitrarily long input or invalid input. How can I read input safely and ensure future inputs won't get borked?
Looking for solutions that work in C and across Linux / Windows.
Thank you for your time.
You are able to read infinite standard input safely. You can just use a continuously reallocating buffer.
#include <stdio.h>
#include <stdlib.h>
char* get_line(size_t* length) {
size_t len = 0;
size_t cap = 4;
char* buffer = malloc(cap);
if (buffer == NULL) {
fprintf(stderr, "Virtual memory exhausted\n");
return NULL;
}
char current;
while ((current = getchar()) != '\n') {
if (len + 1 > cap) {
cap *= 2;
buffer = realloc(buffer, cap);
}
buffer[len++] = current;
}
// One last time for NUL terminator
if (len + 1 > cap) {
cap *= 2;
buffer = realloc(buffer, cap);
}
buffer[len] = 0;
if (length) *length = len;
return buffer;
}
This function will read stdin char-by-char and add it to a string which is returned. Optionally you can ask for its length. Don't forget to free.
int main() {
char* line = get_line(NULL);
printf("You entered: %s\n", line);
free(line);
}
NOTE: This code is meant to be of little verbosity so some checks were omitted. In production code checking realloc and using int for getchar() to test for EOF is necessary.

csv file visualization program [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I would like to write a program that will open a csv file and create its visualization in a txt file.
I mean:
input:
(this is csv file)
apple;orange;strawberry
car;warsaw;ansi
output in txt file
apple|orange|strawberry
car |warsaw| ansi
The idea is that the width of the whole column should be adjusted to the longest expression in it
output in my program
apple|orange|strawberry
|car|warsaw|ansi
|
I have too many separators, and they're not in line
My code:
#include <stdio.h>
#include <string.h>
#include <string.h>
#define MAXLINE 1000
int how_many_delimiter(char array[]);
int main(void)
{
FILE *f,*f_2;
int *size_of_column, counter, hmd, min;
char corrector[] = ";", rows[MAXLINE], *clipboard;
f = fopen("ex-5.csv", "r");
f_2 = fopen("wynik.txt", "w");
fgets(rows, MAXLINE, f);
hmd = how_many_delimiter(rows);
size_of_column = (int*)calloc(hmd,sizeof(int));
min=10;
while(fgets(rows, MAXLINE, f))
{
clipboard = strtok(rows, corrector);
counter=0;
if(strlen(clipboard)>size_of_column[counter])
{
size_of_column[counter] = strlen(clipboard);
}
while(clipboard!=NULL)
{
if(strlen(clipboard)>size_of_column[counter])
{
size_of_column[counter] = strlen(clipboard);
}
clipboard = strtok(NULL,corrector);
counter++;
}
}
fclose(f);
f = fopen("ex-5.csv", "r");
while(fgets(rows, MAXLINE, f))
{
clipboard = strtok(rows, corrector);
counter=0;
while(clipboard!=NULL)
{
fprintf(f_2,"%-*s|",size_of_column[counter], clipboard);
clipboard = strtok(NULL,corrector);
counter++;
}
}
fclose(f);
fclose(f_2);
return 0;
}
int how_many_delimiter(char array[])
{
int counter, i;
i = 0;
counter = 1;
while(array[i]!='\n'&& array[i]!=EOF)
{
if(array[i]==';') counter++;
i++;
}
return counter;
}
Steps to do this (using an alternate to the "%*s", width method):
Loop to get length of longest word in all categories
int len = strlen(longestWord);
Create format string container char formatStr[80];
Populate formatStr: sprintf(formatStr, "%s%d%s", "%", len+5, "s");
+5 is arbitrary, change as needed for space between columns.
Use formatStr in the printf() statements for each word.
So for example the longest word shown in your example is strawberry. My suggestion was to programmatically parse all of the words into buffers, and loop on them, performing strlen() on each to determine longest. Once you've found, in this case, strawberry, len will be 10, so the format specifier would be "%15s" (if you use my recommended +5). But the value 15 will be in an int variable by then (say for example int longest. Since inserting it directly into the normal format string: ( "%longests" ) will not compile, it will need to be packaged up into a format string, formatStr as shown in bullets above, and here:
sprintf(formatStr, "%s%d%s", "%", longest + 5, "s|");
( Will look like: "%s15s|" )
Once this is done, you can use the format string in the printf statements
This then:
fprintf(f_2,"%-*s|",size_of_column[counter], clipboard);
Becomes:
fprintf(f_2,formatStr, clipboard);
(either method will work.)

Why I got segmentation fault when using fgets in C? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I run the program with this command:
./word_search oi < text.txt
and got segmentation fault when running it.
This program is aiming to find where the word (giving as command line arg) exists in a file and print out those lines.
#include <stdio.h>
#include "substring.c"
int main(int argc, char ** argv) {
if(argc == 2) {
char *str;
while(fgets(str, 100, stdin)) {
if(substring(str, argv[1]) != -1) {
printf("Found: %s", str);
}
}
}
return 0;
}
If I change char *str into char str[100] then it works pretty good. Could anyone please tell me why?
The contents in substring.c:
#include <stdio.h>
#include <string.h>
int substring(const char *line, const char *substr) {
int i, j;
int result;
for(i = 0; i <= strlen(line)-strlen(substr); i++) {
result = 0;
if(line[i] == substr[0]) {
int c = i;
for(j = 0; j < strlen(substr); j++) {
if (line[c] != substr[j]) {
result = -1;
}
c++;
}
if(result != -1)
return i;
}
}
return -1;
}
The contents in test.txt are just several lines of meaningless characters.
char *str is an unitialized pointer, it cannot hold the string you are trying to copy into it, either allocate memory to it:
#include <stdlib.h>
#define SIZE 100
char *str = malloc(SIZE); //char has the size of 1 across platforms
Or simply declare it with the size you need:
char str[SIZE];
Pass the size of str to fgets
while(fgets(str, SIZE, stdin))
Of fgets:
Your container will be null terminated, it can only hold a string of SIZE - 1 characters.
All characters above SIZE - 1, including '\n' will remain unread and therefore in the buffer, you might need to clear it.
I suggest you take some time to learn basic C. Especially read about pointers, they are bit hard to get right at first.
In your example, str is a pointer to an undefined memory location.

Fget's automatically \n after reading a string [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 7 years ago.
Improve this question
I have got a really weird issue. After using fgets to read/type a string pointer the next time i want to read a new string from the keyboard the first character automatically becomes \n. How can i avoid/overwrite that ?
I've tried to use
if (firstString[strlen(firstString) - 1] == '\n')
firstString[strlen(firstString) - 1 ] = 0;
but it's still not working.
Thanks for help.
Here is my code :
void citire_text (char *text , int numar_linii)
{
char *text_linie;
int i;
for(i=0;i<=numar_linii;i++)
{
char *text_linie;
text_linie = malloc(MAX*sizeof(char));
fgets(text_linie,MAX,stdin);
strcat(text,text_linie);
}
if (text[strlen(text) - 1] == '\n')
text[strlen(text) - 1 ] = 0;
}
void citire_operatie (char *operatie)
{
fgets(operatie,MAX+2,stdin);
printf("%d",*operatie);
if ((*operatie)=='\n')
printf("YES");
else
printf("NO\n");
}
int main(void)
{
char *text,*operatii;
int numarDeLinii,i;
scanf("%d",&numarDeLinii);
text = malloc(MAX*numarDeLinii*sizeof(char));
operatii = malloc((MAX+2)*sizeof(char));
citire_text(text,numarDeLinii);
int numar_operatii;
scanf("%d",&numar_operatii);
for(i = 1;i<= numar_operatii;i++)
citire_operatie(operatii);
return 0;
}
If i set "numar_operatii" to 1 , in the subprogram citire_operatie fgets won't be even called.
Best to not mix scanf() functions with fgets(). There is a '\n' left-over from when code read scanf("%d", ...
Instead of
scanf("%d",&numarDeLinii);
Read with fgets()
char buf[80];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOF();
if (sscanf(buf, scanf("%d",&numarDeLinii) != 1) Handle_Nonnumeric_Input();
Or make a simple helper function to read an int. Something like:
int Read_int(FILE *istream, const char * prompt, int *dest) {
char buf[80];
while (fgets(buffer, sizeof buffer, stdin)) {
fputs(prompt, stdout);
fflush(stdout);
if (sscanf(buffer, "%d", dest) == 1) return 1;
}
return EOF;
}
// Usage
if (Read_int(stdin, "Enter lines", &numarDeLinii) != 1) return FAIL;
if (Read_int(stdin, "Enter operations", &numar_operatii) != 1) return FAIL;

Resources