Hi i have this text document
Now i want to store only the numbers in an array how can i do it in c language??
www.google.com *** 64
www.victoria.org **** 118
www.example.org *** 120
This should do it:
#include <stdio.h>
// read in up to 10 lines
int LINES[10];
int main(){
int current = 0;
// open file for reading
FILE* file;
file = fopen("file.txt", "r");
// read whole file one char at a time
while (1){
char ch;
if(!fread(&ch, 1, 1, file)){
break;
}
if (ch >= '0' && ch <= '9'){
int val = ch - '0';
LINES[current] *= 10;
LINES[current] += val;
}else if (ch == '\n'){
current += 1;
}
}
// Looping over the results
for (int i = 0; i <= current; i += 1){
printf("Line %d = %d\n", i, LINES[i]);
}
}
There are multiple ways you can do this.
One way is to read the numbers into a temporary char[] array one character at a time with fgetc, then convert it to an int with the use of atoi().
To test if characters are integers, you can use the isdigit function from <ctype.h>, or you can simply test ch >= '0' && ch <= '9', either way works.
Here is some sample code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define NUMLINES 10
#define NUMLEN 5
int main(void) {
FILE *fp;
int LINES[NUMLINES], i, count = 0, ch, blen = 0;
/* static temp buffer, make it bigger if integers will be more than 5 digits */
/* dynamic memory allocation always possible here */
char buffer[NUMLEN+1];
/* opening the file, with error checking */
fp = fopen("urls.txt", "r");
if (!fp) {
fprintf(stderr, "%s\n", "Error reading file");
return 1;
}
/* read each character until EOF */
while ((ch = fgetc(fp)) != EOF) {
/* digit found. add to temp buffer */
if (isdigit(ch)) {
buffer[blen++] = ch;
}
/* stop adding to buffer, now convert and add to array */
if (ch == '\n') {
buffer[blen] = '\0';
LINES[count++] = atoi(buffer);
blen = 0;
}
}
/* print the array */
for (i = 0; i < count; i++) {
printf("LINES[%d] = %d\n", i, LINES[i]);
}
return 0;
}
Which should output:
LINES[0] = 64
LINES[1] = 118
LINES[2] = 120
Related
I have file statistics.txt where is the following data:
Mark = 100
Andy = 200
Then, I wrote this code:
FILE *file_statistics_reading = fopen("statistics.txt", "r");
char line[1024];
int n = 0;
char player[10];
while (fgets(line, sizeof(line), file_statistics_reading) != NULL) {
n = 0;
for (int i = 0; i < 10; i++) {
if ((line[i] > 'A') && (line[i] < 'z')) {
player[n] = line[i];
n = n + 1;
}
}
printf("%s", player);
}
fclose(file_statistics_reading);
I want to extract the names of the players from the text file and print them out, but the output looks like this:
Mark╠╠╠╠╠╠╠╠╠╠╠╠╠
Andy╠╠╠╠╠╠╠╠╠╠╠╠╠
Any solutions?
There are multiple problems in the code:
You forgot to set a null terminator after the name in player, which explains the random bytes in the output. player is an automatic array: its contents are indeterminate at creation time.
You should make player one byte longer.
The test for letters is incorrect: 'A' and 'z' will cause the loop to stop because you use > and < instead of >= and <=
Depending on the character set, some non letter bytes will get printed, such as [, \, ], ^, _ and ` for ASCII. You should use isalpha() from <ctype.h>.
If multiple words appear in the line, the letters in the first 10 bytes, as a single blob for all lines. Separate the output with newlines.
You do not check for the end of line, so 10 bytes are tested even by reading beyond the end of line, whose contents are indeterminate.
Here is a modified version:
#include <ctype.h>
#include <stdio.h>
void print_players(void) {
char line[1024];
FILE *file_statistics_reading = fopen("statistics.txt", "r");
if (file_statistics_reading == NULL) {
perror("cannot open statistics.txt");
return;
}
while (fgets(line, sizeof(line), file_statistics_reading) != NULL) {
char player[11];
size_t n = 0;
for (size_t i = 0; n < sizeof(player) - 1 && line[i] != '\0'; i++) {
if (isalpha((unsigned char)line[i]) {
player[n++] = line[i];
}
}
player[n] = '\0';
printf("%s\n", player);
}
fclose(file_statistics_reading);
}
Here is an alternative approach to print the first word from the line:
#include <stdio.h>
#include <string.h>
void print_players(void) {
char line[1024];
FILE *file_statistics_reading = fopen("statistics.txt", "r");
const char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (file_statistics_reading == NULL) {
perror("cannot open statistics.txt");
return;
}
while (fgets(line, sizeof(line), file_statistics_reading) != NULL) {
int start = strcspn(line, letters); // skip non letters
int len = strspn(line + start, letters); // count letters in word
printf("%.*s\n", len, line + start);
}
fclose(file_statistics_reading);
}
This code reads an input text file, and creates an output file based on its contents.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OUT 0
#define IN 1
#define MAX 28
#define BLOCK 4000
/* Check whether the character is alphanumeric */
int isAlphanumeric(char c) {
return ('a' <= c && c <= 'z') ||
('A' <= c && c <= 'Z') ||
('0' <= c && c <= '9');
}
int main(int argc, char *argv[]) {
int c, state = OUT, length = 0, i, j, counter[MAX];
char word[30], longest_word[30];
FILE *input, *output; /* FILE pointers to open the file */
/* Initialize the counter */
for (i = state; i < MAX; i++)
counter[i] = 0;
/* Open the file */
input = fopen("complete_shakespeare.txt", "r");
output = fopen("word_length_histogram.txt", "w");
/* Keep reading the character in the file */
while ((c = getc(input)) != EOF) {
/* If the character is alphanumeric, record it */
if (isAlphanumeric(c)) {
strncat(word, &c, 1);
}
/* If the character is not alphanumeric, increment the corresponding counter, and additionally, record longest word. */
else {
length = strlen(word);
if (length == 27) strcpy(longest_word, word);
counter[length] += 1;
memset(word, 0, sizeof(word));
}
}
/* If the file ends with a word, record its length */
if (isAlphanumeric(word[0])){
length = strlen(word);
counter[length] += 1;
}
/* print the longest word to the file */
fprintf(output, "%s\n\n", longest_word);
/* Make the histogram */
for (i = 1; i < MAX; i++) {
int dividend = counter[i] / 4000 + 1;
fprintf(output, "%2d %6d ", i, counter[i]);
for (j = dividend; j >= 1; j--){
if (counter[i] != 0)
fprintf(output, "*");
}
fprintf(output, "\n");
}
/* Don't forget to close the FILEs */
fclose(input);
fclose(output);
return 0;
}
It produces the correct output file, but this error comes up whenever I compile it.
B:\CodeBlocks\Projects\Programming in C\hw_4\Homework_4\main.c|44|warning: passing argument 2 of 'strncat' from incompatible pointer type [-Wincompatible-pointer-types]|
The warning seems to come from the only line with strncat. Does anyone know how this can be remedied?
The variable c is declared as having the type int.
int c, state = OUT, length = 0, i, j, counter[MAX];
^^^^^^
So the expression &c used in this call
strncat(word, &c, 1);
has the type int * instead of the type char *.
There is no sense to call strncat for one character. Moreover the array word has indeterminate values because it was not initialized.
char word[30], longest_word[30];
You could write
char word[30], longest_word[30];
word[0] = '\0';
And then something like the following
size_t n = 0;
while ((c = getc(input)) != EOF) {
/* If the character is alphanumeric, record it */
if (isAlphanumeric(c)) {
word[n] = ( char )c;
word[++n] = '\0';
}
/* If the character is not alphanumeric, increment the corresponding counter, and additionally, record longest word. */
else {
if (n == 27) strcpy(longest_word, word);
counter[n] += 1;
n = 0;
word[n] = '\0';
}
}
That is, the variable n will keep track of the current length of the string stored in the array word.
I want to print the data stored in a file which is randomly cased in all caps and strupr() seems to be something that's been listed by someone previously but its not a standard function and may not be cross platform. Is there something which is cross platform?
EDIT 1:
fgets(input1,254,title);
fgets(input2,254,author);
input1[strcspn(input1, "\n")] = '\0';
input2[strcspn(input2, "\n")] = '\0';
printf("<%s> <%s>\n",input1,input2 );
I want to print the string stored in input1 and input2 in uppercase. How to do that?
You can process character by character and use toupper(). Standard function C89 onwards.
Or you can check if character is in between a & z then do a - 32. It will be changed to capital letter.
Here a - 32 = A, because ASCII value of a is 97 and 97 - 32 = 65 and we all know that ASCII value of A is 65.
Code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
char buffer[255] = {'\0'}, c;
int i = 0;
fp = fopen("txt.txt", "r");
if(!fp)
{
perror("txt");
exit(1);
}
while( (c = getc(fp)) != EOF)
buffer[i++] = c;
for( i = 0; buffer[i] != '\0'; i++)
{
if(buffer[i] >= 'a' && buffer[i] <= 'z')
buffer[i] = buffer[i] - 32;
printf("%c", buffer[i]);
}
fclose(fp);
return 0;
}
Output:
HELLO!
THIS IS 2ND LINE.
You can use a custom made function, f.e. upcase(). It reads every character in the file, checks whether it is lowercase or not (if it is, the character is adjusted to uppercase using the toupper() function), stores the whole file content into a buffer and then overwrites the file with the content in the buffer:
FILE* upcase (const char* path)
{
int c, cnt = 0, i = 0, j = 1;
int n = 500;
FILE* fp = fopen(path, "r+");
char* buffer = calloc(n, sizeof(char));
if (!fp || !buffer)
{
return NULL;
}
while ((c = fgetc(fp)) != EOF)
{
if ( i == n )
{
j++;
realloc(buffer, sizeof(char) * (n * j));
if (!buffer)
{
return NULL;
}
i = -1;
}
c = toupper(c);
buffer[i] = c;
i++;
cnt++;
}
for ( int i = 0; i < cnt; i++ )
{
if (fputc(c, fp) == EOF)
{
fclose(buffer);
return NULL;
}
}
return fp;
}
I am trying to get this piece of code to read a line from a file but it's not working. I was wondering if one of you could help me. It was going to read the last 5 lines which I can configure later, but right now I am just trying to get it to read the last line.
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
FILE *myfile = fopen("X:\\test.txt", "r");
int x, number_of_lines = 0, count = 0, bytes = 512, end;
char str[256];
do {
x = fgetc(myfile);
if (x == '\n')
number_of_lines++;
} while (x != EOF); //EOF is 'end of file'
if (x != '\n' && number_of_lines != 0)
number_of_lines++;
printf("number of lines in test.txt = %d\n\n", number_of_lines);
for (end = count = 0; count < number_of_lines; ++count) {
if (0 == fgets(str, sizeof(str), myfile)) {
end = 1;
break;
}
}
if (!end)
printf("\nLine-%d: %s\n", number_of_lines, str);
fclose(myfile);
system("pause");
return 0;
}
Here is a simple solution where you read all lines into a circular line buffer and print the last 5 lines when the end of file has been reached:
#include <stdio.h>
int main(void) {
char lines[6][256];
size_t i = 0;
FILE *myfile = fopen("X:\\test.txt", "r");
if (myfile != NULL) {
while (fgets(lines[i % 6], sizeof(lines[i % 6]), myfile) != NULL) {
i++;
}
fclose(myfile);
for (size_t j = i < 5 ? 0 : i - 5; j < i; j++) {
fputs(lines[j % 6], stdout);
}
}
return 0;
}
Just make a for or while cycle that reads all the file(use fscanf) and when the reading gets to your desired line you save it to a var.
I'm reading:
22:5412:99:00 (...)
From a text file using (ch=fgetc(fp)) != EOF because I don't have only those numbers to read.
Identifying a number is easy with if(ch >= 48 && ch <= 57) but the thing is I want to put those numbers 22, 5412 into an array of integers. However when I read a char it reads part of number since each number is char.
It gets 2 (and not 22 like I want to) and in the next iteration reads the other 2. How can I save each set of numbers into it's own integer?
I hope I was clear enough, thanks!
My idea is to read in each char, and if it is a digit append it to a buffer. Whenever we get a non-digit, we just read the contents of the buffer as a string using sscanf, and clear the buffer for the next value.
#include <stdio.h>
#include <stdlib.h>
int read_buffer(char* buffer, int* sz)
{
int ret;
if (*sz==0) return 0;
buffer[*sz]='\0'; //end the string
sscanf(buffer,"%d", &ret); //read the contents into an int
*sz=0; // clear the buffer
return ret;
}
int main()
{
char buffer[1000];
int sz=0;
char ch;
FILE* input=fopen("input.txt","r");
// "input.txt" contains 22:5412:99:00
while ((ch=fgetc(input))!=EOF)
{
int number;
if (isdigit(ch))
{
buffer[sz++]=ch; // append to buffer
}
else
{
printf("Got %d\n",read_buffer(buffer,&sz)); // read contents of buffer and clear it
}
}
if (sz) // check if EOF occured while we were reading a number
printf("Got %d\n",read_buffer(buffer,&sz));
fclose(input);
return 0;
}
You would need to store the numbers as a string or a char* and use atoi to actually convert it to a number. http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
Assuming your pattern is of the type NN:NNNN:NN:NN, parse on the delimiter, feeding characters into a buffer:
int idx = 0, nIdx = 1;
int firstN, secondN, thirdN, fourthN;
char buf[5];
...
while ((ch=fgetc(fp)) != EOF) {
if (ch != ':') {
buf[idx++] = ch;
}
else {
buf[idx] = '\0';
idx = 0;
switch (nIdx++): {
case 1: firstN = atoi(buf); break;
case 2: secondN = atoi(buf); break;
case 3: thirdN = atoi(buf); break;
}
}
}
buf[idx] = '\0';
fourthN = atoi(buf);
...
I did a full program out of the previous post -- and some testing :-)
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
/* fill `array` with at most `siz` values read from the stream `fp` */
/* return the number of elements read */
size_t fillarray(int *array, size_t siz, FILE *fp) {
int ch;
size_t curr = 0;
int advance_index = 0;
while ((ch = fgetc(fp)) != EOF) {
if (isdigit((unsigned char)ch)) {
array[curr] *= 10;
array[curr] += ch - '0';
advance_index = 1;
} else {
if (advance_index) {
advance_index = 0;
curr++;
if (curr == siz) { /* array is full */
break;
}
}
}
}
return curr + advance_index;
}
int main(void) {
int array[1000] = {0};
int n, k;
n = fillarray(array, 1000, stdin);
if (n > 0) {
printf("%d values read:\n", n);
for (k=0; k<n; k++) {
printf(" %d", array[k]);
}
puts("");
} else {
fprintf(stderr, "no data read\n");
}
return 0;
}
And a test run
$ ./a.out
24555:76423 foobar 76235 jgfs(8) jhg x86-64 passw0rd RS232
[CTRL+D]
8 values read:
24555 76423 76235 8 86 64 0 232