I need to write a function that search inside a string a sequence of letters from the abc ( not numbers) remove them and leave only the first and last two of the sequence. For example if the input string is: dabcemoqmnopqrrtaduvwxaz the output should be: da-cemoqm-rrtadu-xaz
Or is the input is : dabcefLMNOpQrstuv567zyx, the output is : da-cefL-OpQr-v567zyx.
I have a main file abc.c and abc_functions.c.
I am getting a few errors-
abc.c: In function ‘main’:
abc.c:10:5: warning: implicit declaration of function ‘abc_functions’ [-Wimplicit-function-declaration]
abc_functions(str);
^
/tmp/ccmsgqvg.o: In function `main':
abc.c:(.text+0x5f): undefined reference to `abc_functions'
collect2: error: ld returned 1 exit status
Any ideas?
`
#include "shortend_string.h"
#include <string.h>
void abc_functions (char str[])
{
char str[max_size];
char *dst = str;
int j = 0;
int i;
int curr;
for (i=0; i < strlen(str); i++)
{
if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) /*checking that the sequences involves the abc letters only*/
{
for (curr = i; curr < strlen(str); curr++)
{
if (str[curr+1] != str[curr]+1)/* sequences ending point*/
break;
}
}
if (curr >= i+2) /*if sequences is larger than or equal to 2 modify the string*/
{
dst[j++] = str[i];
dst[j++] = '-';
dst[j++] = str[curr];
i = curr; /*resetting the loop*/
}
else
dst[j++] = str[i];
}
dst[j] = '\0';
return(0);
}
`
`
#include <stdio.h>
#include "abc_functions.h"
int main()
{
char str[max_size];
printf("please enter a string:");
fgets(str, max_size, stdin);
printf("\nThe String is:%s", str);
abc_functions(str);
printf("\nThe output is :%s\n" , str);
return 0;
}
`
Note the first error:
implicit declaration of function ‘abc_functions’
The compiler said you lacked to supply an abc_functions() declaration.
Please check:
abc_functions.h contains the proper declartion.
abc_functions.h base directory is given to the compiler (use -Ipath_to_dir).
Also, whenever asking about compilation failures, it's a good idea to provide the compilation command line.
Related
This is my code. I am getting some weird warning's when I run it and I'm confused on why. Warnings on the bottom. My code will still run and the output is correct, however I still want to understand and fix the warnings thanks. I tried to fix all the warnings, however when I do my code won't output correctly anymore. My program fails. So I am confused. Please help!
#include <stdio.h>
#include <stdlib.h>
char s1(char *random);
char s2(char *s2_input, int index);
char strfilter(char *random, char *s2_input, char replacement);
int main()
{
int s1_index = 41;
char s1_random[s1_index];
s1(s1_random);
printf("\ns1 = ");
puts(s1_random);
printf("s2 = ");
int s2_index = 21;
char s2_input[s2_index];
s2(s2_input, s2_index);
if(s2_input[1] == '\0')
{
printf("size too small");
exit(0);
}
printf("ch = ");
char replacement = getchar();
printf("\n");
int filter_index = 41;
strfilter(s1_random, s2_input, replacement);
printf("\ns1 filtered = ");
puts(s1_random);
}
char s1(char *random)
{
int limit = 0;
char characters;
while(characters = ('A' + (rand() % 26))) /* random generatro */
{
if(limit == 41)
{
*(random + 41 - 1) = '\0';
break;
}
*(random + limit) = characters;
limit++;
}
}
char s2(char *s2_input, int index)
{
char array[21] = "123456789012345678901"; /* populated array to make sure no random memory is made */
char input;
int count = 0;
int check = 0;
while(input = getchar() )
{
if(input == '\n')
{
*(s2_input + count) = '\0';
break;
}
else if(input < 65 || input > 90)
{
printf("invalid input");
exit(0);
}
*(s2_input + count) = input;
count++;
}
index = count;
}
char strfilter(char *random, char *s2_input, char replacement) /* replacement function */
{
while(*s2_input)
{
char *temp = random;
while(*temp)
{
if(*temp == *s2_input)
*temp = replacement;
temp++;
}
s2_input++;
}
}
**
Error message:
**
matthew.c:41:22: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
while(characters = ('A' + (rand() % 26))) /* random generatro */
~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
matthew.c:41:22: note: place parentheses around the assignment to silence this warning
while(characters = ('A' + (rand() % 26))) /* random generatro */
^
( )
matthew.c:41:22: note: use '==' to turn this assignment into an equality comparison
while(characters = ('A' + (rand() % 26))) /* random generatro */
^
==
matthew.c:51:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
matthew.c:61:17: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
while(input = getchar() )
~~~~~~^~~~~~~~~~~
matthew.c:61:17: note: place parentheses around the assignment to silence this warning
while(input = getchar() )
^
( )
matthew.c:61:17: note: use '==' to turn this assignment into an equality comparison
while(input = getchar() )
^
==
matthew.c:80:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
}
^
matthew.c:96:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
5 warnings generated.
I tried what the compiler says to do, such as ==, or adding the parenthesis but then my code won't run correctly if I do that. So I am confused.
I tried what the compiler says to do, such as ==, ...
You should not just try any suggestion without understanding it.
Your code is basically correct. You want an assignment.
But assignments in conditions is a very common case of errors. In most cases, there are comparisons used in conditions. The compiler does just warns you that this might be wrong.
Making it a comparison does not make any sense for you.
What you should do instead is using extra brackets:
while(characters = ('A' + (rand() % 26)))
should be changed into
while ((characters = ('A' + (rand() % 26))) != 0)
In the next message you have an additional problem:
while(input = getchar() )
Here the reason for the warning is the same: Might be a typo in a comparison.
But this time, you are missing the actual condition. This loop will iterate until input will become 0. Normally, you will get \n or EOF to indicate you reached the end of line or end of file.
Also, getchar returns an int which means you must use an int variable to store the result. Otherwise you could never distinguish value 255 from EOF.
This line should be
while ((input = getchar()) != EOF )
Regarding your other type of warning:
matthew.c:51:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
I think, that is self explaining. If you define a function with a return type, you are supposed to return something.
If you don't need any return value of that function, define it as void function.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So im supposed to write a Soundex Converter code and print the lines from a file if one of its words has the same Soundex code as the input. I successfully wrote a function for the Soundex conversion but im stuck at the comparing part. Sorry if this sounds trivial but when i compare the words line by line, strcmp seems to fail everytime. Here's the code... Sorry if its too long
#include<string.h>
#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
char *soundex(char *s,char* name)
{
int si = 1;
char c;
//char *s = (char *)malloc(1000);
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
char mappings[] = "01230120022455012623010202";
s[0] = toupper(name[0]);
for(int i = 1, l = strlen(name); i < l; i++)
{
c = toupper(name[i]) - 65;
if(c >= 0 && c <= 25)
{
if(mappings[c] != '0')
{
if(mappings[c] != s[si-1])
{
s[si] = mappings[c];
si++;
}
if(si > 3)
{
break;
}
}
}
}
if(si <= 3)
{
while(si <= 3)
{
s[si] = '0';
si++;
}
}
//printf("%s\n",s);
return s;
}
void search(char line[10000],char str[1000])
{
int i,j=0;
char test[1000];
char s[1000];
char b[1000];
for(i=0;line[i] != '\0';i++)
{
if(line[i] == ' ')
continue;
test[j] = line[i];
j++;
if(line[i+1] == ' ' || line[i+1] == '\0')
{
//soundex(test);
test[j] = '\0';
if(strcmp(soundex(s,test),soundex(b,str)) == 0);
{
printf("%s\n",soundex(s,test));
printf("%s\n",soundex(b,str));
printf("%s",line);
break;
}
j = 0;
memset(test,0,strlen(test));
}
}
}
int main()
{
char a[1000],f[1000];
char s[1000];
gets(a);
//soundex(s,a);
//printf("%s",s);
scanf("%s",f);
FILE *fp=fopen(f,"r");
if(fp==NULL)
{
printf("File doesnot exist bro");
}
else
{
long long linenum=1;
char line[10000];
while(fgets(line,10000,fp)!=NULL) //Or fscanf
{
search(line,a);
//printf("%s",line);
linenum++;
}
}
fclose(fp);
}
The Problem is arising with the strcmp command in the Search function as it prints the lines even after the results differ. I even print the results of the comparison afterwards to be sure. Any leads would be aprreciated. Again sorry for the long code.
Take the ; off. Don't ignore compiler warnings!
prog.c:70:17: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
if(strcmp(soundex(s,test),soundex(b,str)) == 0);
if(strcmp(soundex(s,test),soundex(b,str)) == 0)
also
prog.c: In function ‘search’:
prog.c:68:25: warning: statement with no effect [-Wunused-value]
test[j] == '\0';
and
prog.c: In function ‘main’:
prog.c:89:9: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
gets(a);
Reposting because my first post was no good. I have a question that I'm not really sure how to do. I know the process I'm going for, but am not totally sure how to scan a string into an array so that each character/integer is scanned into a independent element of the array. I'll post the question and the code I have so far, and any help would be appreciated.
Question:
Assume that we have a pattern like the following: ([n][letter])+ in which n is an integer number and letter is one of the lowercase letters from a-z. For example, 2a and 3b are valid expressions based on our pattern. Also, “+” at the end of the pattern means that we have at least one expression (string) or more than one expression attached. For instance, 2a4b is another valid expression which is matched with the pattern. In this question, we want to convert these valid expressions to a string in which letters are repeated n times.
o Read an expression (string) from user and print the converted version of the expression in the output.
o Check if input expression is valid. For example, 2ab is not a valid expression. If the expression is not valid, print “Invalid” in the output and ask user to enteranother expression.
o Sample input1 = “2a”, output = aa
o Sample input2 = “2a3b”, output = aabbb
o You will receive extra credit if you briefly explain what concept or theory you can use to check whether an expression is valid or not.
What I have so far:
#include <stdio.h>
int main()
{
int size, i, j;
char pattern[20];
char vowel[20];
int count[20];
printf("Please enter your string: ");
gets(pattern);
size = strlen(pattern);
for(i=0; i<size; i++)
if((i+1)%2 == 0)
vowel[i] = pattern[i];
else if((i+1)%2 != 0)
count[i] = pattern[i];
for(i=0; i<size/2; i++);
for(j=0; j<count[i]; j++)
printf("%s", vowel[i]);
}
I assumed you want to write the "invalid\n" string on stderr. If not just change the file descriptor given to write.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define MAX_INPUT_SIZE 20
int
check_input(char *input)
{
while (*input)
{
if (*input < '0' || *input > '9')
{
write(2, "invalid\n", 8);
return 1;
}
while (*input >= '0' && *input <= '9')
input++;
if (*input < 'a' || *input > 'z')
{
write(2, "invalid\n", 8);
return 1;
}
input++;
}
return 0;
}
void
print_output(char *input)
{
int i;
while (*input)
{
i = atoi(input);
while (*input >= '0' && *input <= '9')
input++;
for (; i > 0; i--)
write(1, input, 1);
input++;
}
write(1, "\n", 1);
}
int
main()
{
char input[MAX_INPUT_SIZE];
do
{
printf("Please enter your string: ");
fgets(input, MAX_INPUT_SIZE, stdin);
input[strlen(input) - 1] = '\0';
}
while (check_input(input));
print_output(input);
return 0;
}
The steps are:
Read pattern
Check if pattern is valid
Generate output
Since the input length is not specified you have to assume a maximum length.
Another assumption is n is a single digit number.
Now you may read the whole expression with fgets() or read it char by char.
The latter allows you to check for validity as you read.
Lets use fgets() for convenience and in case the expression needs to be stored for later use.
char exp[100]; // assuming at most 50 instances of ([n][letter])
int len;
printf("Input: ");
fgets(exp, 100, stdin);
len = strlen(exp) - 1; // Discard newline at end
An empty input is invalid. Also a valid expression length should be even.
if (len == 0 || len%2 != 0) {
printf("Invalid-len\n");
return 1;
}
Now parse the expression and separately store numbers and letters in two arrays.
char nums[50], letters[50];
invalid = 0;
for (i = 0, j = 0; i < len; i += 2, j++) {
if (exp[i] >= '1' && exp[i] <= '9') {
nums[j] = exp[i] - '0';
} else {
invalid = 1;
break;
}
if (exp[i+1] >= 'a' && exp[i+1] <= 'z') {
letters[j] = exp[i+1];
} else {
invalid = 1;
break;
}
}
Notice that in each iteration if first char is not a number or second char is not a letter, then the expression is considered to be invalid.
If the expression is found to be invalid, nothing to do.
if (invalid) {
printf("Invalid\n");
return 1;
}
For a valid expression run nested loops to print the output.
The outer loop iterates for each ([n][letter]) pattern.
The inner loop prints n times the letter.
printf("Output: ");
for (i = 0; i < len/2; i++) {
for (j = 0; j < nums[i]; j++)
printf("%c", letters[i]);
}
This is a rather naive way to solve problems of this type. It is better to use regular expressions.
C standard library doesn't have regex support. However on Unix-like systems you can use POSIX regular expressions.
like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#define prompt "Please enter your string: "
void occurs_error(const char *src, const char *curr){
printf("\nInvalid\n");
printf("%s\n", src);
while(src++ != curr){
putchar(' ');
}
printf("^\n");
}
bool invalid(char *pattern){
char *p = pattern;
while(*p){
if(!isdigit((unsigned char)*p)){//no number
occurs_error(pattern, p);
break;
}
strtoul(p, &p, 10);
if(!*p || !islower((unsigned char)*p)){//no character or not lowercase
occurs_error(pattern, p);
break;
}
++p;
}
return *p;
}
int main(void){
char pattern[20];
while(fputs(prompt, stdout), fflush(stdout), fgets(pattern, sizeof pattern, stdin)){
pattern[strcspn(pattern, "\n")] = 0;//chomp newline
char *p = pattern;
if(invalid(p)){
continue;
}
while(*p){
int n = strtoul(p, &p, 10);
while(n--)
putchar(*p);
++p;
}
puts("");
}
}
I am trying to create a function which has two arguments, the word, and a letter to search in the word.
The word is actually an array where each letter is an element of the array, e.g. for the word "word", we have the following:
word = [w, o, r, d].
Therefore I have to compare each element of word[ ] to the letter, and if they match the function should return 1, otherwise 0.
The code is the following:
char ltt_srch(char word[], char ltt)//LINE 13
{
int len, i;
len = sizeof(word)/sizeof(word[0]);
for(i = 0; i < len; i++)
{
if(ltt == word[i])
{
return 1;
}
}
return 0;
}
I call ltt_srch in main using this code:
if(ltt_srch(word[len], ltt) == 0)//LINE 51
{
printf("Letter not found.\n");
}
but I get one warning and one note, specifically:
Line 13: [Note] Expected 'char *' but argument is of type 'char'
Line 51: [Warning] passing argument 1 of 'ltt_srch' makes pointer from integer without a cast
The problem is that you are passing word[len] instead of word as your first parameter. If you pass word[len] you will pass the character on the index len of word instead of word itself.
For example if word = "word" and len = 2 then word[len] == 'r'.
Solution:
if(ltt_srch(word, ltt) == 0) instead of if(ltt_srch(word[len], ltt) == 0).
This:
len = sizeof(word)/sizeof(word[0]);
is wrong. You cannot use sizeof inside a function to get the size of an array passed as an argument like that.
You meant:
const size_t len = strlen(word);
You need to search for the terminator, to work with general strings in C.
Also you're calling it wrong, this:
ltt_srch(word[len], ltt)
is subscripting into word which will yield a character, but you want to pass the array itself so it should be
ltt_srch(word, ltt)
Finally, the standard library has this function already, look up strchr():
int ltt_srch(const char *word, chr ltt)
{
return strchr(word, ltt) != NULL;
}
#include <stdio.h>
#include <stdlib.h>
int ltt_srch(char word[], char ltt);
int
main(void) {
char *word = "word";
char key = 'r';
if (ltt_srch(word, key)) {
printf("Letter found.\n");
} else {
printf("Letter not found.\n");
}
return 0;
}
int
ltt_srch(char word[], char ltt) {
int i;
for(i = 0; word[i] != '\0'; i++) {
if(ltt == word[i]) {
return 1;
}
}
return 0;
}
I have the following code:
void toCapital(char name[], int size){
int i = 0;
char *wholeName = name;
for (i = 0; i < size ; i++){
wholeName[i] = toupper(wholeName[i]);
printf("%c", wholeName[i]);
}
}
main()
{
char miNombre[] = "Jason Martin Marx";
toCapital(miNombre, sizeof(miNombre));
}
And the output is:
JASON MA
This code takes a char array and converts all the strings inside into upper case. However, for some reason it stops halfway. Even if i increase the number of times to run the loop, it just adds gibberish at the end instead of the following letter.
If i was to edit the array into something like "Jason Martin Marx Jason Martin Marx" (doubling the string size) then it would print out the upper cased string once as "JASON MARTIN MARX" but not the second time.
Here is the whole code as requested:
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
void myName(char name[], int size){
int i;
for (i = 0; i < size -1; i++){
char currentLetter = name[i];
if (currentLetter == 'a' || currentLetter == 'e' || currentLetter == 'i' || currentLetter == 'o' || currentLetter == 'u' ||
currentLetter == 'A' || currentLetter == 'E' || currentLetter == 'I' || currentLetter == 'O' || currentLetter == 'U'){
printf("Character [%c] located at position %i is a vowel\n", currentLetter, i);
}
else if (currentLetter == ' '){
printf("Character [%c] located at position %i is a space\n", currentLetter, i);
}
else if (currentLetter == '$' || currentLetter == '%'){
printf("Character [%c] located at position %i is a symbol\n", currentLetter, i);
}
else{
printf("Character [%c] located at position %i is a consonant\n", currentLetter, i);
}
}
}
void pyramidA(char name[], int size){
int i;
char *wholeName = name;
int pointer = size-1;
char spaces[80] = "";
for (i = 0; i < (size / 2) ; i++){
printf("%i %s [%s] \n", pointer, spaces, wholeName);
wholeName++; ///erases first letter
wholeName[strlen(wholeName) - 1] = '\0'; /// erases last letter
pointer = pointer - 2;
strcat(spaces," ");
}
}
void toUpper(char name[], int size){
int i = 0;
char *wholeName = name;
printf("%s", wholeName);
for (i = 0; i < size ; i++){
wholeName[i] = toupper(wholeName[i]);
printf("%c", wholeName[i]);
}
}
main()
{
char miNombre[] = "Jason $ Martin % Marx ";
myName(miNombre, sizeof(miNombre));
printf("\n");
pyramidA(miNombre, sizeof(miNombre));
printf("\n");
toUpper(miNombre, sizeof(miNombre));
}
The problem is quite simply that you are modifying the string yourself. You probably think that assigning a pointer to another pointer creates a copy, but it doesn't:
char *wholeName = name;
// …
wholeName[strlen(wholeName) - 1] = '\0'; // <- modifies string in 'name'
If you want a temporary copy of name in wholeName, you must duplicate it, e.g.:
char *wholeName = malloc(size);
name = strcpy(wholeName, name);
// at the end of the function:
free(name);
It would be good style to check the return value of malloc. Also, you must free the same pointer that was returned by malloc, and since you do wholeName++ inside the loop I recycled the name pointer above to store the starting position. (The naming of the pointers is now quite misleading.)
Another thing you can do on gcc is create the output of the preprocessor by compiling with the -E option. There might be something going on that is not obvious by looking at the code before compiling. I ran your code and the output is not the same as your are getting. gcc -E foo.c -o foo.i. Edit foo.i and see if your code has been morphed by the preprocessor in any way.
================ output below ==================
JASON MARTIN MARX
The result may be compiler-dependent:
$ gcc -std=c99 -pedantic test.c
test.c: In function 'toCapital':
test.c:6:5: warning: implicit declaration of function 'toupper' [-Wimplicit-function-declaration]
test.c:7:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
test.c:7:5: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
test.c: At top level:
test.c:11:1: warning: return type defaults to 'int' [enabled by default]
Here's a result from testing the resulting binary on my end:
bash-3.2$ ./a.out
JASON MARTIN MARX^#bash-3.2$
Other than the warnings, I think using sizeof() on an array declared on the stack should be okay. I think your problem is elsewhere, but I don't know where.
EDIT
Now that we have all the code, your function pyramidA() is manipulating the contents of miNombre. That's why your string is truncated.
Use strcpy() within the functions to work with a copy of the string miNombre. This leaves miNombre unchanged.