Cannot print or access char * inside a function - c

The code below does not print nor return the char * temp which I am trying to retrieve from a text file containing a matrix of the form:
4
spQ77377.1 0.000000 0.776030 0.781073 0.804880
spO91086.1 0.776030 0.000000 0.564157 0.559756
spP04578.2 0.781073 0.564157 0.000000 0.302724
spO12164.1 0.804880 0.559756 0.302724 0.000000
The whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char * const getField( char lineBuffer[255], int field ) {
printf( "\n " );
static char temp[30];
int f = 0;
for( int i = 0; lineBuffer[i]!='\n' ; i++ ) {
if( f == field && lineBuffer[i] != ' ' ) {
temp[i] = lineBuffer[i];
printf( "%c", temp[i] );
}
if( lineBuffer[i] == ' ' && lineBuffer[i+1] == ' ' ) {
printf( "||" );
f++;
}
if( f > field ) {
printf( " break " );
printf( "*%s*", temp );
fflush(stdout);
return temp;
}
}
return "!";
}
int main() {
FILE *matrixStream;
matrixStream = fopen( "outfile", "r" );
if ( matrixStream == NULL ) {
printf( "\n\tERROR FILE NOT FOUND!\n" );
exit( 1 );
}
char lineBuffer[255];
fseek( matrixStream, 0, SEEK_SET );
int line = 0;
char ** field1 = malloc( 4 * sizeof( char *) );
while( fgets( lineBuffer, 255, matrixStream ) ) {
if( line != 0 ) {
printf( "\n line = %d ", line-1 );
if( line == 1 ) {
field1[line-1] = malloc( 30 * sizeof( char ) );
strcpy( field1[line-1], getField( lineBuffer, 1 ) );
}
}
line++;
}
printf( "\n" );
fclose( matrixStream );
return 0;
}
My objective is to have the function getField() to return a certain field or column (provided in argument as int field) for a line in the matrix.
For now, I only have the following output and can not seem to understand the problem, there are no error message during compilation with the options -Wall -pedantic. Here is the exact output:
line = 0
||0.000000|| break **
line = 1
line = 2
line = 3
The value of char * temp is not printed between the * characters as it should be.
Thank you in advance for any help or advice you can provide.

you need to terminate your temp buffer, and to have 2 indexes
static char temp[30];
int toff = 0; // temp offset
int f = 0;
for( int i = 0; lineBuffer[i]!='\n' ; i++ ) {
if( f == field && lineBuffer[i] != ' ' ) {
temp[toff++] = lineBuffer[i]; // use temp offset
printf( "%c", temp[i] );
}
if( lineBuffer[i] == ' ' && lineBuffer[i+1] == ' ' ) {
printf( "||" );
f++;
}
if( f > field ) {
temp[toff] = 0; // 0 terminate
printf( " break " );
printf( "*%s*", temp );
fflush(stdout);
return temp;
}
}
of course you should also error out if toff > sizeof(temp)
BTW the reason you get nothing is that temp, being static, is initialized to 0 at startup and you never write anything to temp[0] (beacuse you use the line buffer offset). So temp is an empty string always

Related

C: outputs the total number of times the first word occurs

when I enter a sentence, this code should get the first word and count the how many times repeated.
firstWord(): This function gets the string as a parameter. Then, outputs the total number of times the first word occurs.
(this code consisting of 4 functions and in this func(firstWord()) I should use 'string' as a parameter, in main function I just call the firstWord func. )
number of times the first word occurs.
for ex: sentence is no changes and no suprises
first word no repeated 2 times.
here is the code.
void firstWord(char st3[]){
char firstw[20];
char *ptr;
int i=0;
int count=0;
ptr=strstr(st3,firstw);
while (ptr = '\0')
{
count++;
ptr++;
ptr = strstr(ptr, firstw);
}
printf("First word %s is repeated %d times\n", firstw, count);
}
The function does not make a sense.
You are using the uninitialized array firstw in a call of strtsr as for example
char firstw[20];
//..
ptr=strstr(st3,firstw);
that invokes undefined behavior.
Also there is a typo in the condition of the while statement
while (ptr = '\0')
Instead of using the equality operator == you are using the assignment operator = after which the pointer ptr becomes a null pointer.
At first you need to find the first word in the source string and then count how many times it is present in the source string.
Pay attention to that the function strstr can find a substring that does not form a word that is that is not delimited by white space characters.
Also at least the parameter of the function firstWord should be declared with the qualifier const because the source string is not changed within the function. And the return type of the function should not be void. The function should return the counter and the position and the length pf the first word in the source string as for example by using an object of a structure type.
The function can be implemented for example the following way as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
struct Word
{
char *pos;
size_t length;
size_t counter;
};
struct Word firstWord( const char *s )
{
const char *delim = " \t\n";
struct Word word = { .pos = NULL, .length = 0, .counter = 0 };
while ( *s )
{
s += strspn( s, delim );
if ( *s )
{
size_t n = strcspn( s, delim );
if ( word.pos == NULL )
{
word.pos = ( char * )s;
word.length = n;
word.counter = 1;
}
else
{
if ( n == word.length && strncmp( word.pos, s, n ) == 0 )
{
++word.counter;
}
}
s += n;
}
}
return word;
}
int main( void )
{
const char *s = " A AB A ABC A";
struct Word word = firstWord( s );
if ( word.pos != NULL )
{
printf( "The first word \"%.*s\" is found %zu time(s)\n",
word.length, word.pos, word.counter );
}
}
The program output is
The first word "A" is found 3 time(s)
Using that function you can for example sort an array of strings in the lexicographical order of first words and if the words are equal in the ascending order of their counters in strings.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Word
{
char *pos;
size_t length;
size_t counter;
};
struct Word firstWord( const char *s )
{
const char *delim = " \t\n";
struct Word word = { .pos = NULL, .length = 0, .counter = 0 };
while ( *s )
{
s += strspn( s, delim );
if ( *s )
{
size_t n = strcspn( s, delim );
if ( word.pos == NULL )
{
word.pos = ( char * )s;
word.length = n;
word.counter = 1;
}
else
{
if ( n == word.length && strncmp( word.pos, s, n ) == 0 )
{
++word.counter;
}
}
s += n;
}
}
return word;
}
int cmp( const void *a, const void *b )
{
const char *s1 = *( const char * const * )a;
const char *s2 = *( const char * const * )b;
struct Word word1 = firstWord( s1 );
struct Word word2 = firstWord( s2 );
size_t n = word1.length;
if ( word2.length < n ) n = word2.length;
int result = strncmp( word1.pos, word2.pos, n );
if ( result == 0 )
{
result = ( word2.length < word1.length ) - ( word1.length < word2.length );
if ( result == 0 )
{
result = ( word2.counter < word1.counter ) - ( word1.counter < word2.counter );
}
}
return result;
}
int main( void )
{
const char * s[] =
{
"CCC CCC CCC",
"CCC CCC",
"BB BB",
"A A",
"CC",
"BB",
"CCC",
"A"
};
const size_t N = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N; i++ )
{
puts( s[i]);
}
putchar( '\n' );
qsort( s, N, sizeof( const char * ), cmp );
for ( size_t i = 0; i < N; i++ )
{
puts( s[i]);
}
putchar( '\n' );
}
The program output is
CCC CCC CCC
CCC CCC
BB BB
A A
CC
BB
CCC
A
A
A A
BB
BB BB
CC
CCC
CCC CCC
CCC CCC CCC
If you need to write a function that just determines the first word in a string then it can look the following way as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
struct Word
{
char *pos;
size_t length;
};
struct Word firstWord( const char *s, const char *delim )
{
struct Word word = { .pos = NULL, .length = 0 };
while ( *s && word.pos == NULL )
{
s += strspn( s, delim );
if ( *s )
{
size_t n = strcspn( s, delim );
word.pos = ( char * )s;
word.length = n;
s += n;
}
}
if ( word.pos == NULL )
{
word.pos = ( char * )s;
}
return word;
}
int main( void )
{
const char *s = " A AB BA A";
struct Word word = firstWord( s, " \t\n" );
char first_word[word.length + 1];
strncpy( first_word, word.pos, word.length );
first_word[word.length] = '\0';
printf( "The first word is \"%s\" at position %zu\n",
first_word, word.pos - s );
}
The program output is
The first word is "A" at position 3
You don't consider that "cat can catch mice" should report only 1 occurrence of "cat".
Try this (or something like it):
void firstWord( char st3[] ) {
char *firstw = "EMPTY STRING";
int count = 0;
for( char *ptr = st3; ( ptr = strtok( ptr, " .,-" ) ) != NULL; ptr = NULL )
if( count == 0 ) {
firstw = ptr;
count++;
} else if( strcmp( ptr, firstw ) == 0 )
count++;
printf( "First word %s is repeated %d times\n", firstw, count );
}
Update
With the feedback "didn't work", I've added a few printf's to show that it does work...
void firstWord( char st3[] ) {
char *firstw = "EMPTY STRING";
int count = 0;
printf( "Using: '%s'\n", st3 );
for( char *ptr = st3; ( ptr = strtok( ptr, " .,-" ) ) != NULL; ptr = NULL )
if( count == 0 ) {
firstw = ptr;
count++;
} else if( strcmp( ptr, firstw ) == 0 )
count++;
printf( "First word %s occurs %d times\n\n", firstw, count );
free( st3 );
}
void my_main(void) {
firstWord( strdup( "cat can catch mice" ) );
firstWord( strdup( "cat cat catch cat" ) );
firstWord( strdup( " cat cat catch cat" ) );
firstWord( strdup( "dog dog dog dog dog" ) );
firstWord( strdup( "" ) );
}
Output:
Using: 'cat can catch mice'
First word cat occurs 1 times
Using: 'cat cat catch cat'
First word cat occurs 3 times
Using: ' cat cat catch cat'
First word cat occurs 3 times
Using: 'dog dog dog dog dog'
First word dog occurs 5 times
Using: ''
First word EMPTY STRING occurs 0 times

Code giving runtime error in codeforce prob 474 A

I am a beginner in codeforces. I am stuck in problem 474 A where I am getting runtime error. But I can't any fault in it. I use C. Here is my code:
#include<stdio.h>
int main()
{
int a, i, j, b, arr[102];
char ch, str2[101], c;
char str1[30] = "qwertyuiopasdfghjkl;zxcvbnm,./";
for (i = 0; i<30; i++)
arr[(str1[i])] = i;
scanf("%c%s", &ch, str2);
if (ch == 'R')
{
for (i = 0; str2[i]; i++)
{
printf("%c", str1[(arr[str2[i]] - 1)]);
}
printf("\n");
}
else {
for (i = 0; str2[i]; i++)
{
printf("%c", str1[(arr[str2[i]] + 1)]);
}
printf("\n");
}
return 0;
}
Can you find what is wrong in it?
Please try this, if I understood the problem correctly this works.
// MOLE is typing to the right or to the left of 3 rows of keys
// qwertyuiop
// asdfghjkl;
// zxcvbnm,./
// encoded as: !qwertyuiop!asdfghjkl;!zxcvbnm,./!
// where '!' detects input errors
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main( void )
{
int i;
char ch;
char str2[101];
char kstr1[50];
char *poschar; // pointer to char
int int_poschar = 0;
int translated_position = 0;
int right = 0;
int left = 0;
strcpy( kstr1, "!qwertyuiop!asdfghjkl;!zxcvbnm,./!" );
printf( "\n Please enter R or L and press enter\n" );
scanf( " %c ", &ch );
ch = toupper( ch );
if ( ch == 'R' || ch == 'L' ) ; // good input say nothing
else
{
printf( "\nPlease try again with L or R ( or l or r ) " );
exit( 0 );
}
printf( "\n Please enter a word and press enter\n" );
scanf( " %100s", str2 );
strcpy( str2, strlwr( str2 ) );
if ( ch == 'R' )
{
printf( "\nRIGHT translate:\n%s\n", str2 );
right = 1;
}
else if ( ch == 'L' )
{
printf( "\nLEFT translate:\n%s\n", str2 );
left = 1;
}
getchar( );
for ( i = 0; str2[i]; i++ )
{
poschar = strchr( kstr1, str2[i] );
if ( poschar != NULL )
{
int_poschar = poschar - kstr1; // find prev pos in array
if ( right )
translated_position = int_poschar - 1;
else if ( left )
translated_position = int_poschar + 1;
else
{
printf( "\n you've got a bug !" );
exit( 0 );
}
if ( kstr1[translated_position] == '!' )
{
if ( right )
printf( "\n not possible, MOLE wrote 1 key to the right" );
else
printf( "\n not possible, MOLE wrote 1 key to the left" );
getchar( );
exit( 0 );
}
printf( "%c", kstr1[int_poschar - 1] );
} // endif ( poschar != NULL )
}
exit( 0 );
}

C Program passing file-io to function

This program is supposed to shift a sentence by a certain amount.
If i have a shift of 3 then the letter a should be d. However when I pass the string into my shift function it doesn't shift any of my values.
#include <stdio.h>
#define MAX_LEN 100
void decode(char *sentence, int shift);
int main(void)
{
FILE *ifp;
FILE *ofp;
char str[MAX_LEN];
int shift_by = 0;
scanf("%d", &shift_by);
ifp = fopen("input.txt", "r");
ofp = fopen("output.txt", "w");
if (ifp == NULL) {
printf("FILE doesnt open");
return 1;
}
while(fgets(str, MAX_LEN, ifp) != NULL) {
shift(str, shift_by);
fprintf(ofp," %s", str);
}
fclose(ifp);
fclose(ofp);
return 0;
}
void decode(char *sentence, int shift)
{
char *p;
p = sentence;
if ((*p >= 'a') && (*p <= 'z')) {
*p = (*p - 'a') + shift % 26 + 'a';
}
if ((*p >= 'A') && (*p <= 'Z')) {
*p = (*p - 'A' + shift) % 26 + 'A';
}
}
Please try the code below it works. You thought 'decode' but you typed 'shift'. I simplified the code a bit. Now you can experiment to make it work with pointers.
Have fun.
#include <stdio.h>
#define MAX_LEN 100
void decode( char *sentence, int shift );
int main( void )
{
FILE *ifp;
FILE *ofp;
char str[MAX_LEN];
int shift_by = 0;
printf( "\nPlease enter shift by and press enter\n" );
scanf( " %d", &shift_by );
ifp = fopen( "input.txt", "r" );
ofp = fopen( "output.txt", "w" );
if ( ifp == NULL )
{
printf( "FILE doesnt open" );
return 1;
}
while ( fgets( str, MAX_LEN, ifp ) != NULL )
{
decode( str, shift_by );
fprintf( ofp, " %s", str );
}
fclose( ifp );
fclose( ofp );
return 0;
}
void decode( char *sentence, int shift )
{
int i = 0;
char p;
while ( p = sentence[i] )
{
if ( ( p >= 'a' ) && ( p <= 'z' ) )
{
p = ( p - 'a' ) + shift % 26 + 'a';
}
if ( ( p >= 'A' ) && ( p <= 'Z' ) )
{
p = ( p - 'A' + shift ) % 26 + 'A';
}
sentence[i] = p;
i++;
}
}

C Program file-io user input

This program takes a a file name which contains a particular sentence and shifts by a certain amount.
if I have Hello and shift by 22 it should be Dahhk, This worked properly when I didn't enter the file name and had the file name in the program manually like
ifp = fopen( "input.txt", "r" );
However when I have the user enter the file name and the input is Hello and shift by 22 the output becomes D{‚‚…
ifp = fopen( name, "r" );
I tried using scanf("%s", name);
and I tried using fgets(name, sizeof(name), stdin);
both produce the same results
I am not sure how to fix this issue.
#include <stdio.h>
#define MAX_LEN 100
void decode( char *sentence, int shift );
int main( void )
{
FILE *ifp;
FILE *ofp;
char str[MAX_LEN];
int shift_by = 0;
char name[100];
printf("Program name: \n");
scanf("%s", name);
printf( "Please enter shift by and press enter\n" );
scanf( " %d", &shift_by );
ifp = fopen( name, "r" );
ofp = fopen( "output.txt", "w" );
if ( ifp == NULL )
{
printf( "FILE doesnt open" );
return 1;
}
while ( fgets( str, MAX_LEN, ifp ) != NULL )
{
decode( str, shift_by );
fprintf( ofp, " %s", str );
}
fclose( ifp );
fclose( ofp );
return 0;
}
void decode( char *sentence, int shift )
{
int i = 0;
char p;
while ( p = sentence[i] )
{
if ( ( p >= 'a' ) && ( p <= 'z' ) )
{
p = ( p - 'a' ) + shift % 26 + 'a';
}
if ( ( p >= 'A' ) && ( p <= 'Z' ) )
{
p = ( p - 'A' + shift ) % 26 + 'A';
}
sentence[i] = p;
i++;
}
}
OP's code has a small error:
// p = ( p - 'a' ) + shift % 26 + 'a';
p = ( p - 'a' + shift) % 26 + 'a';
Curiously OP coded correctly with
p = ( p - 'A' + shift ) % 26 + 'A';
The hint was "Hello" --> "D{‚‚…" worked for uppercase, yet not lowercase.

"Overwrite" repeated values in a file (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 8 years ago.
Improve this question
Hello i have a little problem, and i cannot find a solution yet. I have a file (data.txt) with the next information:
5,5,6,2,5,2
1,4,2,3,7,2
4,2,5,2,3,4
5,5,6,2,5,2
4,5,2,6,2,4
2,1,5,6,3,2
And i want to set to 0 all the repeated lines, for example: 5,5,6,2,5,2 appears two times, so the final file must look as follows:
0,0,0,0,0,0
1,4,2,3,7,2
4,2,5,2,3,4
0,0,0,0,0,0
4,5,2,6,2,4
2,1,5,6,3,2
I have tried with auxiliar files but cannot get the solution, i would be so apreciated with any help.
I can set any of the two lines to 0 but not both of them, and the same if the same line appears more than twice.
You can achieve that by:
Opening the input/output file on "r+" mode first
Systematically getting characters from the file line by line into an array of character arrays
Comparing lines with each other, setting characters other than commas to zero characters when they are paired
Seeking back in the file
Writing lines back into the file, separating them with new lines
To detect pairings properly, you could possibly follow the following logic:
Pick a line, create a variable along with it and set it to 1
Compare that line with the others
In case of a match, set the variable to 0 and keep on comparing your line with the rest
... until the end, replacing the non-comma characters to zero characters with each match
After checking with them all, modify or don't modify your initially picked line depending on the state of that variable which you had set to 1 initially
Here's a code that works, should work without flaw unless you have insufficient memory:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
void settozero( char * line ) {
for ( int i = 0; line[i] != '\0'; i++ )
if ( line[i] != ',' )
line[i] = '0';
}
int main( ) {
char ** lines = NULL;
FILE * input;
if ( ( input = fopen( "input", "r+" ) ) == NULL ) {
printf( "error at line %d", __LINE__ );
return -1;
}
int currentchar;
int newline = 1;
int linecount = 0;
int lineindex;
int linesize;
while ( ( currentchar = fgetc( input ) ) != EOF ) {
if ( newline ) {
linecount++;
lineindex = 0;
linesize = 128;
lines = realloc( lines, linecount * sizeof * lines );
lines[linecount - 1] = malloc( linesize );
newline = 0;
}
if ( lineindex == linesize ) {
linesize *= 3;
lines[linecount - 1] = realloc( lines[linecount - 1], linesize );
}
if ( currentchar == '\n' ) {
newline = 1;
currentchar = '\0';
}
lines[linecount - 1][lineindex++] = currentchar;
}
if ( !newline ) {
if ( lineindex == linesize )
lines[linecount - 1] = realloc( lines[linecount - 1], linesize + 1 );
lines[linecount - 1][lineindex] = '\0';
}
int * linestoskip = calloc( linecount, sizeof * linestoskip );
for ( int i = 0; i < linecount; i++ ) {
if ( linestoskip[i] )
continue;
int unique = 1;
for ( int j = i + 1; j < linecount; j++ ) {
if ( linestoskip[j] )
continue;
if ( strcmp( lines[i], lines[j] ) == 0 ) {
unique = 0;
settozero( lines[j] );
linestoskip[j] = 1;
}
}
if ( !unique )
settozero( lines[i] );
}
free( linestoskip );
fseek( input, 0L, SEEK_SET );
for ( int i = 0; i < linecount; i++ ) {
for ( int j = 0; lines[i][j] != '\0'; j++ ) {
fputc( lines[i][j], input );
}
if ( i != linecount - 1 || newline )
fputc( '\n', input );
free( lines[i] );
}
free( lines );
putchar( 10 );
return 0;
}

Resources