Using char and int together - c

I'm trying to use char for identifying the outcome of the text.
For example, i have a file.txt which contains letters like: iiixxiix
I would like to replace the i's with numbers: 123xx67x and so on.
What should I be doing, to get such outcome? I can't seem to use int to replace a char ( srt[i] = c; ) and I have no idea how to move foward from the problem.
#include <stdio.h>
int main()
{
FILE *fp;
char str[60];
int i;
int c = 1;
/* opening file for reading */
fp = fopen("file.txt" , "r");
if(fp == NULL)
{
perror("Error opening file");
return(-1);
}
if( fgets (str, 22, fp)!=NULL )
{
for (i = 0; i < 22; i++)
{
if (str[i] == 'i')
{
str[i] = '0';
}
printf("%c", str[i]);
}
}
fclose(fp);
return(0);
}

The C specification requires that all digit characters are encoded contiguously. And if you look at the common and mostly used ASCII encoding you will see that the digits are encoded from 48 to 57.
That means it's very easy to use the integer index i (modulo 10) and add '0' to get the characters.
Simple example:
for (int i = 0; i < 22; ++i)
{
printf("Index %d to character '%c'\n", i, (char) (i % 10 + '0'));
}

Related

Why are there extra characters in the output of the following C code?

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

Is there a way to print all string in capital letters without using strupr function as its not a standard library function?

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

C Store number of a text file in an array

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

Why do I get weird number after reading from file?

I get weird values after reading from file (i should be max 100 but I get more), and if someone would explain when to use & * ** in pointers in a simple why couse my english is not very good when it comes to programing I would be grateful
This program should read words from file and if there is a number in the word change it to first letter of that word. If you have any suggestions on how I could change file reading I would also appreciate that. I am new to C (in school I did C++ but very basic levels)
# include <stdio.h>
# define MAX_LEN 100
int File_reading();
int main()
{char buffer;
File_reading();
}
int File_reading( )
{
FILE *stream;
char buffer[MAX_LEN + 1];
int i, ch;
stream = fopen("data.txt","r");
for (i = 0; (i < (MAX_LEN+1));i++)
{
if (((ch = fgetc(stream)) != EOF) && (ch != '\n'))
{
buffer[i] = ch;
}
}
buffer[i] = '\0';
if (fclose(stream))
perror("fclose error");
for (i=0;(i<(MAX_LEN+1));i++){
printf("%c \n", buffer[i]);
}
}
You're not stopping the loop when the file is over, and you're overstepping the array bound! That's terrible. Fix the loop, like this:
char buffer[MAX_LEN + 1];
size_t i;
for (i = 0; i != MAX_LEN; ++i)
{
int c = fgetc(stream);
if (c == EOF) { break; }
buffer[i] = c;
}
buffer[i] = '\0';

Formatting a C Program

So I have a program that takes a file and reads in character by character and prints the character and the hexadecimal equivalent.
`
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *labFile;
char buf;
labFile = fopen("lab1.dat", "r");
if (labFile == NULL) perror("Error opening file\n");
while( (buf = fgetc(labFile) ) != EOF){
if(("%x", buf)< 16){
printf("%c 0%x\n", buf, buf);
}
else
printf("%c %x\n", buf, buf);
}
fclose(labFile);
return 0;
}
`
The program works the way I need it to except for one thing. I need the program to output the hex number on top then the character directly underneath the number and this process needs to continue horizontally.
Any help would be greatly appreciated!
You should output the characters as hex first, and save each read in character that has been printed until you run out of columns on your screen. You can then move to the next line, and print out the characters that were saved underneath the hex output.
You can simplify your logic to format your hex output into a single print statement.
When printing out the character, you need to have a plan to represent non-printable characters. In the sample program below, we handle it by printing two consecutive dots.
void print_chars (unsigned char *p, int num) {
int i;
for (i = 0; i < num; ++i) {
printf("%s%c%s",
isprint(p[i]) ? " " : ".",
isprint(p[i]) ? p[i] : '.',
(i < num-1) ? " " : "\n");
}
}
int main() {
FILE *labFile;
char buf;
int count = 0;
int num = COLUMNS/3;
char printed[num];
labFile = fopen("lab1.dat", "r");
if (labFile == NULL) perror("Error opening file\n");
while( (buf = fgetc(labFile) ) != EOF) {
printf("%s%02x", count ? " " : "", buf);
printed[count++] = buf;
if (count == num) {
count = 0;
putchar('\n');
print_chars(printed, num);
}
}
fclose(labFile);
if (count) {
putchar('\n');
print_chars(printed, count);
}
return 0;
}
The number of columns is divided by 3 since each character takes about 3 columns for output (2 hex characters, and a space). Retrieving the number of columns is system dependent, but you can just plug in 80 if you wish.
You could do something like this. ASSUMES your lines are < 100 chars long. Not safe.
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *labFile;
char buf[100];
labFile = fopen("lab1.dat", "r");
if (labFile == NULL) perror("Error opening file\n");
while(fgets(buf, 100, labFile)) {
if(rindex(buf, '\n')) *rindex(buf, '\n') = 0;
int i, n = strlen(buf);
for(i = 0; i != n; i++) {
printf("0%x ", buf[i]);
}
printf("\n");
for(i = 0; i != n; i++) {
printf("%c ", buf[i]);
}
printf("\n");
}
fclose(labFile);
return 0;
}

Resources