Adding incremental integers to end of string in C - c

need some help with sprintf. I keep running into the error 'sprintf' makes pointer from integer without a cast.
a was declared in the main function to be char a[1000]
int
next_statement(char *a, int n) {
int c, i,z;
for (i=0; i < n && (c = getchar()) != EOF; i++) {
if (c == CHAR_SEMI) {
consume_char('\n');
break;
}
a[i] = c;
}
for(z=0; z<n;z++){
if (c == CHAR_SEMI) {
a[i-3] = 'x';
sprintf(a[i-2], "%d", z);
a[i-1] = ';';
a[i] = '\0';
return i; /* index when ; was read, so the length of saved. */
}
else if (i >= n) {
printf("%s Line too long.\n", ERROR_PREFIX);
exit(EXIT_FAILURE);
}
}
return 0;
}

In this line a[i-2] is single character. It will not represent the character pointer.
sprintf(a[i-2], "%d", z);
so you can try like this,
sprintf(&a[i-2], "%d", z);
From the man page of sprintf
int sprintf(char *str, const char *format, ...);
It requires the first argument as a character pointer.

As you've written, a[i-2] denotes the char, not a char *, as required by sprintf() as it's first parameter. You need to supply the pointer for the string to write on.
[] is the Array subscripting operator. You need not use that operator. So, instead of
sprintf(a[i-2], "%d", z);
you can use like
sprintf( (a+i-2), "%d", z);

sprintf() takes first argument as a char * type, But your mention here as a[i-2] character type,
So you can give like this
sprintf( ((a+i)-2) ,"%d", z);

Related

It's not printing the new array. What could be the reason?

#include <stdio.h>
char q[50];
int doo(int p, int n, char* s) {
int i = 0, j = 0;
while (s[i] != '\0') {
if ((i < p) && (i > (p + n))) {
q[j] = s[i];
++j;
}
i++;
}
puts(p);
}
int main() {
char s[50];
int n, p;
printf("<--program by gautam-->\n");
printf("enter the string-->");
gets(s);
printf("\nenter the numbers of character to be deleted and position-->");
scanf("%d%d", &n, &p);
--p;
doo(p, n, s);
return 0;
}
The task is to delete certain elements of a string by asking the user the position and number of elements to delete. I'm trying to copy all elements except those whose position is provided by user, but I'm getting no output at all.
The fundamental error in your code is that you are using the && operator in the test inside your while loop, whereas you should be using the || operator: if either of the conditions is true, then add the character to the output string.
Also, your doo function is declared as returning an int but it doesn't return anything: I fixed this in the code below by returning j (the count of characters copied) but, as you never use that, you may want to redeclare the function as void, instead.
You are also attempting to print p with the puts function, where you most likely want to print q (I can put this one down to a typo).
Lastly: Never use the gets function! Why is the gets function so dangerous that it should not be used? Use fgets(), instead - it's much safer, as it will never read in more characters than you tell it to, so the buffer won't overflow (if you specify the correct size).
Here's a 'fixed' version of your code, with comments added where I've made changes:
#include <stdio.h>
char q[50];
int doo(int p, int n, char* s)
{
int i = 0, j = 0;
while (s[i] != '\0') {
if ((i < p) || (i > (p + n))) { // Need OR not AND here
q[j] = s[i];
++j;
}
i++;
}
q[j] = '\0'; // Add nul terminator (don't need if only calling once, but best to have it anyway)
puts(q); // Should be printing "q" (result string) NOT "p" (position).
return j; // MUST return something - here, the count of characters
}
int main()
{
char s[50];
int n, p;
printf("<--program by gautam-->\n");
printf("enter the string-->");
fgets(s, 50, stdin); // NEVER use gets - it's been removed from the language!
printf("\nenter the numbers of character to be deleted and position-->");
scanf("%d%d", &n, &p);
--p;
doo(p, n, s);
return 0;
}

fscanf-- trying to scan txt file of ints, fscanf only reads 1s

I'm trying to use fscanf to read a file containing 25 ints and store them in memory. However, it appears that for the first 12 values, instead of scanning the actual int in the file fscanf is always showing up as 1. The 13th value shows up as -1, and then the while loop in the code below terminates. Any idea why this might be? Thanks for your help.
#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"
#define ROWS 5
#define COLS 5
void load_file(FILE* file, int** p);
int main()
{
FILE* f1;
f1 = fopen("twenty-five-ints.txt", "r");
int p=0;
int* matrix = &p;
load_file(f1, &matrix);
}
void load_file(FILE* file, int** p) {
*p = malloc(25*sizeof(int));
int number = 0;
int i = 0;
while (fscanf(file, "%d", &number) != EOF) {
*(*p + i) = fscanf(file, "%d", &number);
printf("%d ", *(*p + i));
i++;
}
printf("\n");
}
The printf statement inside the while loop prints out 12 ones separated by spaces, followed by a -1.
There are two things to mention.
Remove one fscanf() call. Othersise, you'll end up losing every alternative value scanned.
fscanf() does not return the scanned value. In case a macth is found, it stores the scanned value in the supplied argument (&number). Use the argument to get the scanned value. You can make use of the return value to check for the suucess os the call to fscanf().
Quoting the man page, (emphasis mine)
The scanf() family of functions scans input according to format as described below. This format may contain conversion specifications; the results from such conversions, if any, are stored in the locations pointed to by the pointer arguments that follow format. [...]
You should not fscanf() twice and you should compare fscanf() to the number of expected fields to be scanned.
while ((i < 25) && (fscanf(file, "%d", (*p + i)) == 1))
printf("%d ", *(*p + i++));
Also, fscanf() does not return the scanned value, what would you expect it to return in this case?
fscanf(file, "%s%d%", &string, &integer);
Aditionally Consider:
Using index notation to dereference the pointer.
Using an aditional pointer to avoid confusion.
Checking the return value from malloc()
void
load_file(FILE *file, int **data)
{
int *pointer;
size_t i;
*data = NULL; // So you can test this after the call to the function
pointer = malloc(25 * sizeof(**data));
/* ^ if this is a constant, this doesn't make a lot of sense */
/* because you can use an array instead. */
if (pointer == NULL)
return;
for (i = 0 ; ((i < 25) && (fscanf(file, "%d", &pointer[i]) == 1) ; ++i)
printf("%d ", pointer[i]);
printf("\n");
*data = pointer;
}
In my opinion, this function is poorly designed. You can't verify if the read values where in fact 25, nor can you specify that anywhere. If you want a function to read a given number of integers with a maximum try this
size_t
load_file(FILE *file, int **data, size_t maximum)
{
int *pointer;
size_t i;
*data = NULL; // So you can test this after the call to the function
pointer = malloc(maximum * sizeof(**data));
if (pointer == NULL)
return;
for (i = 0 ; ((i < maximum) && (fscanf(file, "%d", &pointer[i]) == 1) ; ++i)
;
*data = pointer;
return i;
}
With this function, you can do this
int *data;
// We assume that FILE * is a valid stream
size_t count = load_file(file, &data, 25);
if (data != NULL)
{
for (size_t i = 0 ; i < count ; ++i)
fprintf(stdout, "%d ", data[i]);
fputc('\n', stdout);
free(data);
}

String comparison function

I am new to C and am trying to figure out and learn why my code isn't working. I understand that in C a string is basically an Array of each character. So I have been trying to search through the array to find the letter a and then print something if it is found. But my program keeps crashing every time I try to run it.
Here is my code:
#include <stdio.h>
void Display(char ch[]);
int main() {
char c[50];
printf("Enter String: ");
gets(c);
Display(c);
return 0;
}
void Display(char ch[]) {
int i;
for (i = 0; i < (sizeof(ch)); i++) {
if (strcmp(ch[i],"a") == 0) {
printf( "Yes");
}
}
}
When I run my program I enter a random string for example "fdas" and press enter. Then it crashes =\
Please remember I am new to C. I am a Java programmer if that helps with any explanations.
This is wrong
if(strcmp(ch[i],"a") == 0)
it should be
if (ch[i] == 'a')
and also, sizeof(ch) is not giving you the length of the string, for that you need strlen(), your Display() function should look like this to work
void Display(char *ch) {
size_t i;
size_t length;
if (ch == NULL)
return;
length = strlen(ch);
for (i = 0 ; i < length ; i++) {
if (ch[i] == 'a') {
printf( "Yes");
}
}
}
also, using gets() is unsafe, and deprecated, usefgets()
fgets(c, sizeof(c), stdin);
is better than gets(c) because it will prevent buffer overflow, note that I've used the sizeof operator in this case, because c is an array of char and the sizeof operator will give it's size in bytes, and since 1 char == 1 byte then it works.
In the case of the Display() function, it's not the same because there the sizeof operator will give the size of the type of ch, and since what you really need is the count of characters that ch points to, so you must use strlen() or compute the length yourself.

c check two strings for same characters

Im just starting to learn C programming and for exercise i found one task. First i have to scan in two strings. Then i have to compare them character by character and if there are any same characters i have to print out the amount of the same characters.
It has to be done with pointers. So lets i have "boat" and "ship" so the program would return 0. But if it were "boat" and "soap" it would return 2.
This is what i've got so far but when i run it it gives me errors. I put the errors in comments.
Thanks in advance for your help.
#include <stdio.h>
#include <string.h>
int number_of_same_characters(char *, char *);
int main()
{
char * first[100];
char * second[100];
int result = 0;
printf("Enter first string\n");
gets(*first);
printf("Enter second string\n");
gets(*second);
result = number_of_same_characters(*first, *second);
printf("%d\n", result);
return 0;
}
int number_of_same_characters(char *p, char *q){ //i get this error here - error: invalid type argument of unary ‘*’ (have ‘int’)
int counter = 0;
for(int j = 0; *p[j] != '\0' || *q[j] != '\0'; ++j){ //i get this error here - error: invalid type argument of unary ‘*’ (have ‘int’)
if(strcmp(*p[j], *q[j])){
++counter;
}
}
return counter;
}
Mainly you've got a lot of extra *'s littering the program. The variable declarations should be:
char first[100];
char second[100];
The input calls should be†:
gets(first);
gets(second);
The method call should be:
result = number_of_same_characters(first, second);
And finally there shouldn't be any dereferences in the for loop.
for(int j = 0; p[j] != '\0' || q[j] != '\0'; ++j){
if(strcmp(p[j], q[j])){
++counter;
}
}
That'll get you closer, though there are still a couple of problems. As a hint, the || operator is suspect, and you don't need to use strcmp.
† It's worth pointing out that gets() is a dangerous function that can lead to buffer overflows. It's okay to use when you're just starting out, but don't let it become a habit, and don't ever use it in production code!
You defined character arrays incorrectly and incorrectly are using operator *.
Try the following
#include <stdio.h>
#include <string.h>
#define N 100
int number_of_same_characters( const char *, const char * );
int main()
{
char first[N];
char second[N];
int result = 0;
size_t n;
printf( "Enter first string: ");
fgets( first, N, stdin );
n = strlen( first );
if ( first[n - 1] == '\n' ) first[n - 1] = '\0';
printf( "Enter second string: ");
fgets( second, N, stdin );
n = strlen( second );
if ( second[n - 1] == '\n' ) second[n - 1] = '\0';
result = number_of_same_characters( first, second );
printf( "%d\n", result );
return 0;
}
int number_of_same_characters( const char *p, const char *q )
{
int counter = 0;
int i;
for( i = 0; p[i] != '\0' && q[i] != '\0'; ++i )
{
if ( p[i] == q[i] ) ++counter;
}
return counter;
}
If to enter boat and soap then the output will be
2

To insert a substring in the given string:Error:15 [Warning] return makes integer from pointer without a cast

I wish to insert a substring in the main string from the given position c which is user entered but i am constantly getting this warning
Header File:
char insstr(char a[100],char b[100],int c){
int i,j,t;
while(b[i]!='\0'){
i++;
}
i=t;
i=0;
for(j=c;j<t;j++){
a[j]=b[i];
i++;
}
return a;
}
Main File:
#include<stdio.h>
#include"Q7.h"
main(){
char x[100],y[100],f;
printf("Enter the main string \n");
gets(x);
printf("Enter the substring \n");
gets(y);
printf("Enter the position from where you want to enter the string");
scanf("%d",f);
printf("%s",insstr(x,y,f));
}
Strings are usually represented as char arrays i.e. char[] or char*. Since you are returning a string from the function, the return type should be char*.
char* insstr(char a[100],char b[100],int c)
{
/* ... */
}
You don't initialize i in insstr() before using it. This:
int i,j,t;
while(b[i]!='\0')
{
i++;
}
Should be:
int i,j,t;
i = 0;
while(b[i] != '\0')
{
i++;
}
Or, instead of reinventing the wheel, you should be using strlen(b) instead.
This is just wrong:
i=t;
i=0;
You didn't initialize t, and you are assigning to i twice. You end up obliterating whatever was stored in i. And of course, you are overwriting the contents of a without taking care of what was there. You are not inserting a string into a, you are replacing part of it with b. And then of course, as mentioned in other comments and answers, the return value should be char *.
Why not something as simple as this:
char *insstr(char *a, char *b, int c)
{
size_t a_len = strlen(a);
size_t b_len = strlen(b);
strcat(a, b);
reverse(a+c, a_len-c);
reverse(a+a_len, strlen(b));
reverse(a+c, a_len-c+b_len);
return a;
}
Where reverse() is:
void reverse(char *str, size_t len)
{
size_t i = 0, j = len-1;
while (i < j)
{
char tmp = str[i];
str[i] = str[j];
str[j] = tmp;
i++;
j--;
}
}
The algorithm works by concatenating b to a and then doing the appropriate swaps to move b into the right spot. In general, you can think of a as a string that can be decomposed into two blocks, ac, where c is the block after the insertion point where b will stay. When you concatenate b to the original string, you get acb. Moving b to the spot before c is a matter of reversing c, reversing b, so that you get a c_r b_r, and then you reverse c_r b_r, getting bc - just what you wanted.
A small example of how to use it:
int main(void)
{
char str1[100] = "Hello!";
char str2[] = ", world";
insstr(str1, str2, 5);
printf("%s\n", str1);
return 0;
}
This prints:
Hello, world!
Remember that you must make sure that a is indeed large enough to hold b. In general, you should pass the size of a as an argument, so that you can take appropriate action if a is not big enough, or, alternatively, you can make your code ensure that insstr() is not called if a is not big enough.
And please don't use gets(). Always use fgets(). It doesn't hurt, it is not complex, and it shows that you care.
NOTE: this idea is generalized in the book Programming Pearls as an efficient and elegant way to implement string rotations (which is what you want after appending b). Off the top of my head, I think it is mentioned in the "Aha! Algorithms" column.
#include<stdio.h>
#include<stdlib.h>
int insstr ( char *str, char *ins, int at) {
int each;
int len = 0;
int lenstr = 0;
int lenins = 0;
while ( str[lenstr] != '\0') {
lenstr++;
}
while ( ins[lenins] != '\0') {
lenins++;
}
if ( at > lenstr) {
at = lenstr; // force at to length of str if needed
}
len = at;
for ( each = 0; each <= lenins; each++) {
str[len] = ins[each]; // append ins onto str
len++;
}
return 1; // return true
}
int main() {
char input[300];
char substr[300];
char position[300];
int insert;
int each;
printf ( "Enter a string.\n");
fgets ( input, sizeof ( input), stdin);
each = 0;
while ( input[each] != '\n') {
each++;
}
input[each] = '\0'; // remove new-line
printf ( "Enter sub-string.\n");
fgets ( substr, sizeof ( substr), stdin);
each = 0;
while ( substr[each] != '\n') {
each++;
}
substr[each] = '\0'; // remove new-line
printf ( "Enter position to insert sub-string.\n");
fgets ( position, sizeof ( position), stdin);
insert = atoi ( position); // make position an integer
if ( insstr ( input, substr, insert)) {
printf ( "%s\n", input); // insert is successful. print it.
}
return 0;
}

Resources