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

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

Related

Can you lend me a hand with this word counting code?

This code don't count words properly. I don't know if it is wrong on the for or what. Need help.
#include <stdio.h>
#include <stdlib.h>
int count_p(char sentence[100]) {
int i, m = 1;
for (i = 0 ; i < 100 ; i++) {
if (sentence[i] == ' ') {
m += 1;
}
}
return(m);
}
void main() {
char s[100];
int p;
printf("Sentence here: ");
scanf("%s", &s[50]);
p = count_p(sentence);
printf("Words: %d", p);
printf("\n");
}
The %s in scanf stops reading when it found a whitespace. Therefore, ' ' won't appear in s unless it was there as indeterminate value in uninitialized variable.
You can use fgets to read a whole line.
Here is a fixed code that also checks for end of the string.
#include <stdio.h>
#include <stdlib.h>
int count_p(char sentence[100]) {
int i, m = 1;
for (i = 0 ; i < 100 && sentence[i] != '\0'; i++) {
if (sentence[i] == ' ') {
m += 1;
}
}
return(m);
}
int main(void) {
char s[100];
int p;
printf("Sentence here: ");
fgets(s, sizeof(s), stdin);
p = count_p(s);
printf("Words: %d", p);
printf("\n");
return 0;
}
scanf("%s", &s[50]);
Not a correct way to take input and writing at index which is out of bound. Do this instead -
scanf("%99[^\n]", s); // this will read 99 characters and until '\n' is encountered
In main you function call is incorrect -
p = count_p(sentence); // sentence is not declares in main
Call like this -
p = count_p(s); // pass s instead of sentence to function
Also in function count_p change ccondition in for loop as -
size_t i;
size_t len=strlen(s);
for (i = 0 ; i < len ; i++)
You see &s[50] means that you pass a pointer to the 51-th element of s, you then try to access s from the beginning but, the first 50 characters in s were not yet initialized, this leads to undefined behavior.
Also, your loop from 0 to 99 will have the same issue since you might input a string of less than 100 characters, in that case you would be accessing uninitialized data too.
You can fix your program by changing this
scanf("%s", &s[50]);
to
scanf("%99s", s);
and then
for (i = 0 ; i < 100 ; i++) {
to
for (i = 0 ; s[i] != '\0' ; i++) {
because scanf() will append a '\0' to make the array a valid c string, that's also the reason for the "%99s".
Another problem is that, if you want white space characters not to make scanf() stop reading, you need a different specifier, because "%s" stops at the first white space character, this is a suggestion
scanf("%99[^\n]", s);
Or you can do as #MikeCAT suggested and go with fgets(). But be careful with the trailing '\n' in case of fgets().
And finally, altough highly unlikely in this situation, scanf() might fail. To indicate success it returns the number of specifiers actually matched, thus it might indicate partial success too. It's fairly common to see the return value of scanf() ignored, and it's very bad when you have a "%d" specifier for example because then the correspoinding parameter might be accessed before initializing it.
The statement scanf("%s", &s[50]); is in correct in your situation.Since you want to enter a sentence separated by spaces,the correct way of doing it is :
scanf(" %99[^\n]s",sentence);
That will prevent buffer overflow and allow space between words.Also your program does not seem to count words correctly if the sentence has consecutive whitespaces.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count_p(char *sentence);
void main()
{
char sentence[100];
printf("Sentence here: ");
scanf(" %99[^\n]s",sentence);
int p = count_p(sentence);
printf("Words: %d", p);
printf("\n");
}
int count_p(char *sentence)
{
int len = strlen(sentence);
int x = 0 , wordCount = 0;
for( int n = 0 ; n < len ; n++ )
{
x++;
if( sentence[n] == ' ' )
x = 0;
if( x == 1 )
wordCount++;
}
return wordCount;
}

C program Need help fixing my code for a word sort program

Hi I am still new to c and have been working on this word sort program for some time now. the guidelines are:
Write a program that sorts a series of words entered by the user. Assume that each word is no more than 20 characters long. Stop reading when the user enters an empty word. Store each word in a dynamically allocated string, using an array of pointers (use the read_line function). After all lines have been read sort the array. Then use a loop to print the words in sorted order.
The problem I seem to be having is that the program will accept words but when I enter the empty word it goes to a new line and nothing happens. An help or advice would be greatly appreciated. here is my code so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
#define LIM 20
int read_line(char str[], int n);
void sort_str(char *list[], int n);
int alpha_first(char *list[], int min_sub, int max_sub);
int main(void)
{
char *list[LIM];
char *alpha[LIM];
char word_str[LEN];
int word, i, j, num_count = 0;
for(;;){
printf("Enter a word: ");
scanf("%s", &word);
if(word == NULL)
break;
else
read_line(word_str, LEN);
list[i] = malloc(strlen(word_str) + 1);
strcpy(list[i], word_str);
alpha[i] = list[i];
}
sort_str(alpha, i);
for(i = 0; i < num_count; ++i){
printf("Sorted: ");
puts(list[i]);
}
return (0);
}
int read_line(char str[], int n)
{
int ch, i = 0;
while ((ch = getchar()) != '\n')
if (i < n)
str[i++] = ch;
str[i] = '\0';
return i;
}
void sort_str(char *list[], int n)
{
int i, index_of_min;
char *temp;
for (i= 0; i < n - 1; ++i) {
index_of_min = alpha_first(list, i, n - 1);
if (index_of_min != i) {
temp = list[index_of_min];
list[index_of_min] = list[i];
list[i] = temp;
}
}
}
int alpha_first(char *list[], int min_sub, int max_sub){
int i, first;
first = min_sub;
for(i = min_sub + 1; i <= max_sub; ++i){
if(strcmp(list[i], list[first]) < 0){
first = i;
}
}
return (first);
}
Your logic flow is flawed. If a word is entered, the scanf() will eat it from stdin and store a null-terminated string at the address of the integer 'word'. Any more than 3/7 chars entered, (32/64 bit, allowing for the null terminator), will start corrupting the stack. read_line() will then only have the line terminator to read from stdin, (assuming the UB doesn't blow it up first).
The problem I seem to be having is that the program will accept words but when I enter the empty word it goes to a new line and nothing happens.
There are several problems with this:
char word_str[LEN];
int word, i, j, num_count = 0;
/* ... */
scanf("%s", &word);
if(word == NULL)
break;
First, scanf("%s", &word) scans whitespace-delimited strings, and to that end it skips leading whitespace, including newlines. You cannot read an "empty word" that way, though you can fail to read a word at all if the end of the input is reached (or an I/O error occurs) before any non-whitespace characters are scanned.
Second, you are passing an inappropriate pointer to scanf(). You should pass a pointer to a character array, but you instead pass a pointer to an int. It looks like maybe you wanted to scan into word_str instead of into word.
Third, your scanf() format does not protect against buffer overflow. You should provide a field width to limit how many characters can be scanned. Moreover, you need to be sure to leave room for a string terminator.
Fourth, you do not check the return value of scanf(). If it fails to match any characters to the field, then it will not store any. Since it returns the number of fields that were successfully scanned (or an error indicator), you can detect this condition.
One way to correct the scanf() and "empty word" test would be:
int result;
result = scanf("%*[ \t]%19[^ \t\n]", word_str);
if (result < 1) break;
(That assumes a fixed maximum word length of 19 to go with your declared array length of 20.) You have several additional problems in your larger code, large among them that read_line() attempts to read the same data you just read via scanf() (in fact, that function looks altogether pointless). Also, you never update num_count, and after calling sort_str() you lose track of the number of strings you've read by assigning a new value to variable i.
There may be other problems, too.

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

why does NULL condition terminate after 3 chars

I wrote this function which is supposed to read a string into an array up to the NULL char which represents the end of the string in the line. But it somehow doesn't quite work.
int main(void){
int MAX = 39;
char number1[MAX + 1];
int i;
read_array(number1, MAX);
for(i = 0; i <= MAX; i++)
printf("%c", number1[i]);
return 0;
}
int read_array(char* number, int size) {
printf("\nEnter an integer number at a maximum of 39 digits please.\n");
int result = 0;
char* i;
for (i = number; *i != NULL; i++)
scanf("%c", i);
return result;
}
No matter how many chars I type, as I print the result it just gives me the first 3 chars and I don't understand why. Any idea? THX
As I said earlier, scanf doesn't null-terminate your strings for you. If you want to read until the user hits enter/return, check for that. You can do that by replacing your for-loop with this do-while-loop:
do {
scanf("%c", i); // read the data into i *before* the loop condition check
} while (*i++ != '\n'); // check for '\n' (unless you expect the user to
// actually type the null character)
#NedStark point about i pointing to junk memory is correct. The data in number1 is never initialized, so it's just filled with junk. Your loop condition (*i != NULL) is checked before the scanf call, which means the loop condition is just checking old, junk data (and not the correct value).
The problem is in your loop
for (i = number; *i != NULL; i++)
scanf("%c", i);
After incrementing i, i points to the next memory location which contains garbage data because it
hasn't been properly initialized. Probably you want to something like:
char c;
i = number;
do
{
scanf("%c", &c);
*i = c;
++i;
} while (c!='\n')
*i = '\0';

C program, Reversing an array

I am writing C program that reads input from the standard input a line of characters.Then output the line of characters in reverse order.
it doesn't print reversed array, instead it prints the regular array.
Can anyone help me?
What am I doing wrong?
main()
{
int count;
int MAX_SIZE = 20;
char c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
while(c != EOF)
{
count = 0;
c = getchar();
arr[count++] = c;
getReverse(revArr, arr);
printf("%s", revArr);
if (c == '\n')
{
printf("\n");
count = 0;
}
}
}
void getReverse(char dest[], char src[])
{
int i, j, n = sizeof(src);
for (i = n - 1, j = 0; i >= 0; i--)
{
j = 0;
dest[j] = src[i];
j++;
}
}
You have quite a few problems in there. The first is that there is no prototype in scope for getReverse() when you use it in main(). You should either provide a prototype or just move getReverse() to above main() so that main() knows about it.
The second is the fact that you're trying to reverse the string after every character being entered, and that your input method is not quite right (it checks an indeterminate c before ever getting a character). It would be better as something like this:
count = 0;
c = getchar();
while (c != EOF) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
That will get you a proper C string albeit one with a newline on the end, and even possibly a multi-line string, which doesn't match your specs ("reads input from the standard input a line of characters"). If you want a newline or file-end to terminate input, you can use this instead:
count = 0;
c = getchar();
while ((c != '\n') && (c != EOF)) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
And, on top of that, c should actually be an int, not a char, because it has to be able to store every possible character plus the EOF marker.
Your getReverse() function also has problems, mainly due to the fact it's not putting an end-string marker at the end of the array but also because it uses the wrong size (sizeof rather than strlen) and because it appears to re-initialise j every time through the loop. In any case, it can be greatly simplified:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0) {
dest[j] = src[i];
j++;
i--;
}
dest[j] = '\0';
}
or, once you're a proficient coder:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0)
dest[j++] = src[i--];
dest[j] = '\0';
}
If you need a main program which gives you reversed characters for each line, you can do that with something like this:
int main (void) {
int count;
int MAX_SIZE = 20;
int c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
c = getchar();
count = 0;
while(c != EOF) {
if (c != '\n') {
arr[count++] = c;
c = getchar();
continue;
}
arr[count] = '\0';
getReverse(revArr, arr);
printf("'%s' => '%s'\n", arr, revArr);
count = 0;
c = getchar();
}
return 0;
}
which, on a sample run, shows:
pax> ./testprog
hello
'hello' => 'olleh'
goodbye
'goodbye' => 'eybdoog'
a man a plan a canal panama
'a man a plan a canal panama' => 'amanap lanac a nalp a nam a'
Your 'count' variable goes to 0 every time the while loop runs.
Count is initialised to 0 everytime the loop is entered
you are sending the array with each character for reversal which is not a very bright thing to do but won't create problems. Rather, first store all the characters in the array and send it once to the getreverse function after the array is complete.
sizeof(src) will not give the number of characters. How about you send i after the loop was terminated in main as a parameter too. Ofcourse there are many ways and various function but since it seems like you are in the initial stages, you can try up strlen and other such functions.
you have initialised j to 0 in the for loop but again, specifying it INSIDE the loop will initialise the value everytime its run from the top hence j ends up not incrmenting. So remore the j=0 and i=0 from INSIDE the loop since you only need to get it initialised once.
check this out
#include <stdio.h>
#include <ctype.h>
void getReverse(char dest[], char src[], int count);
int main()
{
// *always* initialize variables
int count = 0;
const int MaxLen = 20; // max length string, leave upper case names for MACROS
const int MaxSize = MaxLen + 1; // add one for ending \0
int c = '\0';
char arr[MaxSize] = {0};
char revArr[MaxSize] = {0};
// first collect characters to be reversed
// note that input is buffered so user could enter more than MAX_SIZE
do
{
c = fgetc(stdin);
if ( c != EOF && (isalpha(c) || isdigit(c))) // only consider "proper" characters
{
arr[count++] = (char)c;
}
}
while(c != EOF && c != '\n' && count < MaxLen); // EOF or Newline or MaxLen
getReverse( revArr, arr, count );
printf("%s\n", revArr);
return 0;
}
void getReverse(char dest[], char src[], int count)
{
int i = count - 1;
int j = 0;
while ( i > -1 )
{
dest[j++] = src[i--];
}
}
Dealing with strings is a rich source of bugs in C, because even simple operations like copying and modifying require thinking about issues of allocation and storage. This problem though can be simplified considerably by thinking of the input and output not as strings but as streams of characters, and relying on recursion and local storage to handle all allocation.
The following is a complete program that will read one line of standard input and print its reverse to standard output, with the length of the input limited only by the growth of the stack:
int florb (int c) { return c == '\n' ? c : putchar(florb(getchar())), c; }
main() { florb('-'); }
..or check this
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
char *my_rev(const char *source);
int main(void)
{
char *stringA;
stringA = malloc(MAX); /* memory allocation for 100 characters */
if(stringA == NULL) /* if malloc returns NULL error msg is printed and program exits */
{
fprintf(stdout, "Out of memory error\n");
exit(1);
}
else
{
fprintf(stdout, "Type a string:\n");
fgets(stringA, MAX, stdin);
my_rev(stringA);
}
return 0;
}
char *my_rev(const char *source) /* const makes sure that function does not modify the value pointed to by source pointer */
{
int len = 0; /* first function calculates the length of the string */
while(*source != '\n') /* fgets preserves terminating newline, that's why \n is used instead of \0 */
{
len++;
*source++;
}
len--; /* length calculation includes newline, so length is subtracted by one */
*source--; /* pointer moved to point to last character instead of \n */
int b;
for(b = len; b >= 0; b--) /* for loop prints string in reverse order */
{
fprintf(stdout, "%c", *source);
len--;
*source--;
}
return;
}
Output looks like this:
Type a string:
writing about C programming
gnimmargorp C tuoba gnitirw

Resources