Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I need to make a code that identifies the longest string of characters that a separated by space. If there are characters of same length, write them both.
Ex:
Input = Java flow car tree
Output = Java flow tree
Her is the code i wrote
#include <stdio.h>
#include <stdlib.h>
int main()
{
char cuv[100], big[100];
int i;
printf("Scrieti cuvintele\n");
gets(cuv);
cuv[0] = big[0];
for(i = 0; cuv[i] = '/0'; i++){
if(cuv[i] > big[i]){
big[i] = cuv[i];
}
}
printf("%s", big);
return 0;
}
The problem is i dont know very well how char works. So i have little clue on what to do. I ask of you on how to use the char set to be able to count strings in a specific way.
Here is a very simple solution. Try to understand the code. Note the code uses some of the functions from #include<string.h>. So, before going through the code please go through string.h header file and understand the standard functions it provides.
Anyways, here is a very basic program,(feel free to modify it to your needs)
#include<stdio.h>
#include<string.h>
#define MAX 256
int main(){
char input[MAX],*tmp=NULL;
char *word_list[MAX],*word=NULL;
int flag[MAX];
int i=0,index=0,m=0,largest_len=0;
//Get Input From User
printf("Enter Input:\n");
fgets(input,MAX,stdin);
//If using fgets then use strchr() to locate '\n' and replace it with '\0'(null terminating char)
if((tmp=strchr(input,'\n')) != NULL){
*tmp='\0';
}
//Use strtok() function to split the sentence/input into words separated by space
//and store them in an array of char pointers(or more like array of strings)
word = strtok(input," ");
word_list[index] = word;
index++;
while(word != NULL && i<MAX){
word=strtok(NULL," ");
if(word != NULL){
word_list[index] = word;
index++;
}
}
//find the word with the largest lenght
for(i=0;i<index;i++){
if(strlen(word_list[i]) >= largest_len){
largest_len = strlen(word_list[i]);
}
}
//Then store the index of words which have their lenght equal to the largest lenght
for(i=0;i<index;i++){
if(strlen(word_list[i]) == largest_len){
flag[m] = i;
m++;
}
}
//Print the largest words
m=0;
printf("Largest Word('s):");
for(i=0;i<index;i++){
if(flag[m] == i){
printf("%s ",word_list[i]);
m++;
}
}
return 0;
}
The code you've posted doesn't seem to even come close to what you're trying to do -- so much so that it's really not salvageable towards a solution.
That said, think about your "large" (complete) problem as a series of smaller problems instead; each smaller problem is easier to solve than the single larger problem. Your problems seem to be:
1) Input your raw data.
2) Split your raw data into words. You could manually walk through your data looking for spaces and doing what you feel appropriate when you find them, or you could figure out how to use strtok() to parse data for you. Given where you are with your language understanding, doing it manually is probably a better learning experience.
3) Determine the length of the largest word in your collection.
4) Go through your entire collection and output each word whose length is equal to that largest length.
For problem 1, you seem to have this accomplished (but pay attention to the suggestions people have given you about better ways to do it).
Problem 2 might be the most challenging. There are several ways one can go about it. I'm not going to provide a solution, but this snippet is a small start:
for (i = 0; cuv[i] != '\0'; ++i) {
/* do something */
}
Pay attention to the middle term of the for loop; it's not making an assignment to cuv[i] (I point this out because in your posted program, you are making an assignment, which is really not what you intend.) It is comparing the character to the standard C string termination.
You'll need to look at each character as you go through the loop and decide if you are increasing the current word, ending the previous word, starting a new word, or just skipping repetitive whitespace.
You'll need to store a pointer to each word somewhere so that the full set of words will be available to steps 3 and 4.
Note that you could perform step 3 while you're doing this but you should not for now. It would make your program more efficient, but it merges the steps together and while learning, you don't need that.
Problem 3 requires you to be aware that strlen(const char *s) will return the length of s, where s is a properly terminated C string.
To solve this you will simply iterate through your full set of words and inspect the length of each; if the length is greater than the previous maximum you will increase your stored maximum. Something like:
unsigned int maxLength = 0;
for (i = 0; i < numberOfWords; ++i) {
if (strlen(word[i]) > maxLength)
maxLength = strlen(word[i]);
}
Finally, for step 4 you will iterate through your list of words again, deciding which ones to print out. Something like:
for (i = 0; i < numberOfWords; ++i) {
if (strlen(word[i]) == maxLength)
printf("%s\n", word[i]);
}
Related
I'm trying to make a binary number calculator in c and I'm running into issues of my for loops doubling the size of my second array and adding the first array onto the end. I'm really confused because I thought you couldn't increase the size after already declaring it. It is happening in my equation reading function as well but in this ones complement function it's a bit simpler to see. Any ideas of how to fix this?the codethe output
welcome to stack-overflow. From next time please use inline code editor to put your code instead of images. I have taken effort put your code in the answer itself to explain the problem. Please consider this as courtesy. Its very unusual to do it. But as you are a new member, I'm doing it.
// Cole carson's original code from image:
char * onescomp(char x[16], char y[16]){
int i;
for(i=0;i<=15;i++){
if(x[i] == '0'){
y[i] = '1';
continue;
}
else if(x[i] == '1'){
y[i] = '0';
continue;
}
}
return y;
}
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[16];
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}
Answer:
You don't need continue; in if-else blocks.
You need to add '\0' in the last cell of cb3n array. so puts() knows when string ends & stop printing.
so to quickly fix this issue you can create array with extra cell and assign all values as '\0'. so after copying fifteen 1's there will be '\0' in the end. I think in your case those extra zeros being printed might be garbage values. It looks like array is doubling but it isn't, its just printing values beyond allocated memory because '\0' has not been provided.
//Quick fix
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[17]={'\0'}; // <--- quick fix
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}
I wrote this code in C, where I wanted to extract words from str, then store them in char word[] (one by one), and send it to another function- palindrome. However, the words are not being formed properly. I'm new to this language so I don't want to use pointers or something else. I want to do it in the most simple way possible. Could you please suggest modifications to the code so that the words get formed properly?
int main()
{
char str[100];
int a=0, l, p=0;
printf("Enter the text \n");
gets(str);
l=strlen(str);
for(int i=0;i<l;i++)
{
char word[100]; int a=0;
if(str[i]==' '||str[i]=='\0')
{
for(int j=p;j<i;j++)
{
word[a]=str[j];
a++;
}
printf("This \n");
puts(word);
palindrome(a,word);
}
}
return 0;
}
Basic things in C don't mean easy to understand. I advise you to understand this code well in order to understand why using high level functions while being a beginner is not necessarily a good thing.
#include <unistd.h>
int main()
{
char buffer;
while(read(0, &buffer, 1) > 0)
write(1, &buffer, 1);
return 0;
}
Since you are an enthusiastic learner and have already tried to solve a problem, the best way to help you is to provide you the guidelines which will assure that you will end up solving your issue successfully.
Pointers
You do not want to use pointers. But what pointers are? Nothing more than variables pointing to a certain position in memory, being aware of the type. You already use arrays, but arrays are memory sections having a type and a size. That section has a start address, so your array is actually not very different from a pointer. So, the intent to avoid using pointers was already breached by the use of arrays, but I think I understand what you want. You want to minimalize pointer arithmetics.
Understandable, implementable solution
You can iterate the characters of your array and store the first non-space character index since the last space you have encountered and find the next space. At that point, you can create a new array of a size which matches the number of characters in that interval and copy the characters from the interval question into that array. Since you are learning C, I will provide you an algorithm that you can implement (this is not actual program code)
wordStart <- -1
lastSpace <- -1
index <- 0
while (index < sizeof(input)) do
if (input[index] != ' ') then
if (wordStart == lastSpace) then
wordStart <- index
end if
else
if (wordStart == lastSpace) then
wordStart <- index
lastSpace <- index
else
lastSpace <- index
//create array of characters, having lastSpace - wordStart elements
//copy the elements between the index of lastSpace and wordStart - 1 into your new array
//pass that new array into your call to palindrom
end if
end if
index <- index + 1
end while
I'm trying to create a complete C program to read ten alphabets and display them on the screen. I shall also have to find the number of a certain element and print it on the screen.
#include <stdio.h>
#include <conio.h>
void listAlpha( char ch)
{
printf(" %c", ch);
}
int readAlpha(){
char arr[10];
int count = 1, iterator = 0;
for(int iterator=0; iterator<10; iterator++){
printf("\nAlphabet %d:", count);
scanf(" %c", &arr[iterator]);
count++;
}
printf("-----------------------------------------");
printf("List of alphabets: ");
for (int x=0; x<10; x++)
{
/* I’m passing each element one by one using subscript*/
listAlpha(arr[x]);
}
printf("%c",arr);
return 0;
}
int findTotal(){
}
int main(){
readAlpha();
}
The code should be added in the findTotal() element. The output is expected as below.
Output:
List of alphabets : C C C A B C B A C C //I've worked out this part.
Total alphabet A: 2
Total alphabet B: 2
Total alphabet C: 6
Alphabet with highest hit is C
I use an array to count the number of the existence of each character,
I did this code but the display of number of each character is repeated in the loop
int main()
{
char arr[100];
printf("Give a text :");
gets(arr);
int k=strlen(arr);
for(int iterator=0; iterator<k; iterator++)
{
printf("[%c]",arr[iterator]);
}
int T[k];
for(int i=0;i<k;i++)
{
T[i]=arr[i];
}
int cpt1=0;
char d;
for(int i=0;i<k;i++)
{int cpt=0;
for(int j=0;j<k;j++)
{
if(T[i]==T[j])
{
cpt++;
}
}
if(cpt>cpt1)
{
cpt1=cpt;
d=T[i];
}
printf("\nTotal alphabet %c : %d \n",T[i],cpt);
}
printf("\nAlphabet with highest hit is : %c\n",d,cpt1);
}
There is no way to get the number of elements You write in an array.
Array in C is just a space in the memory.
C does not know what elements are actual data.
But there are common ways to solve this problem in C:
as mentioned above, create an array with one extra element and, fill the element after the last actual element with zero ('\0'). Zero means the end of the actual data. It is right if you do not wish to use '\0' among characters to be processed. It is similar to null-terminated strings in C.
add the variable to store the number of elements in an array. It is similar to Pascal-strings.
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 10
char array[ARRAY_SIZE + 1];
int array_len(char * inp_arr) {
int ret_val = 0;
while (inp_arr[ret_val] != '\0')
++ret_val;
return ret_val;
}
float array_with_level[ARRAY_SIZE];
int array_with_level_level;
int main() {
array[0] = '\0';
memcpy(array, "hello!\0", 7); // 7'th element is 0
printf("array with 0 at the end\n");
printf("%s, length is %d\n", array, array_len(array));
array_with_level_level = 0;
const int fill_level = 5;
int iter;
for (iter = 0; iter < fill_level; ++iter) {
array_with_level[iter] = iter*iter/2.0;
}
array_with_level_level = iter;
printf("array with length in the dedicated variable\n");
for (int i1 = 0; i1 < array_with_level_level; ++i1)
printf("%02d:%02.2f ", i1, array_with_level[i1]);
printf(", length is %d", array_with_level_level);
return 0;
}
<conio.h> is a non-standard header. I assume you're using Turbo C/C++ because it's part of your course. Turbo C/C++ is a terrible implementation (in 2020) and the only known reason to use it is because your lecturer made you!
However everything you actually use here is standard. I believe you can remove it.
printf("%c",arr); doesn't make sense. arr will be passed as a pointer (to the first character in the array) but %c expects a character value. I'm not sure what you want that line to do but it doesn't look useful - you've listed the array in the for-loop.
I suggest you remove it. If you do don't worry about a \0. You only need that if you want to treat arr as a string but in the code you're handling it quite validly as an array of 10 characters without calling any functions that expect a string. That's when it needs to contain a 0 terminator.
Also add return 0; to the end of main(). It means 'execution successful' and is required to be conformant.
With those 3 changes an input of ABCDEFGHIJ produces:
Alphabet 1:
Alphabet 2:
Alphabet 3:
Alphabet 4:
Alphabet 5:
Alphabet 6:
Alphabet 7:
Alphabet 8:
Alphabet 9:
Alphabet 10:-----------------------------------------List of alphabets: A B C D E F G H I J
It's not pretty but that's what you asked for and it at least shows you've successfully read in the letters. You may want to tidy it up...
Remove printf("\nAlphabet %d:", count); and insert printf("\nAlphabet %d: %c", count,arr[iterator]); after scanf(" %c", &arr[iterator]);.
Put a newline before and after the line of minus signs (printf("\n-----------------------------------------\n"); and it looks better to me.
But that's just cosmetics. It's up to you.
There's a number of ways to find the most frequent character. But at this level I recommend a simple nested loop.
Here's a function that finds the most common character (rather than the count of the most common character) and if there's a tie (two characters with the same count) it returns the one that appears first.
char findCommonest(const char* arr){
char commonest='#'; //Arbitrary Bad value!
int high_count=0;
for(int ch=0;ch<10;++ch){
const char counting=arr[ch];
int count=0;
for(int c=0;c<10;++c){
if(arr[c]==counting){
++count;
}
}
if(count>high_count){
high_count=count;
commonest=counting;
}
}
return commonest;
}
It's not very efficient and you might like to put some printfs in to see why!
But I think it's at your level of expertise to understand. Eventually.
Here's a version that unit-tests that function. Never write code without a unit test battery of some kind. It might look like chore but it'll help debug your code.
https://ideone.com/DVy7Cn
Footnote: I've made minimal changes to your code. There's comments with some good advice that you shouldn't hardcode the array size as 10 and certainly not litter the code with that value (e.g. #define ALPHABET_LIST_SIZE (10) at the top).
I have used const but that may be something you haven't yet met. If you don't understand it and don't want to learn it, remove it.
The terms of your course will forbid plagiarism. You may not cut and paste my code into yours. You are obliged to understand the ideas and implement it yourself. My code is very inefficient. You might want to do something about that!
The only run-time problem I see in your code is this statement:
printf("%c",arr);
Is wrong. At this point in your program, arr is an array of char, not a single char as expected by the format specifier %c. For this to work, the printf() needs to be expanded to:
printf("%c%c%c%c%c%c%c%c%c%c\n",
arr[0],arr[1],arr[2],arr[3],arr[4],
arr[5],arr[6],arr[7],arr[8],arr[9]);
Or: treat arr as a string rather than just a char array. Declare arr as `char arr[11] = {0};//extra space for null termination
printf("%s\n", arr);//to print the string
Regarding this part of your stated objective:
"I shall also have to find the number of a certain element and print it on the screen. I'm new to this. Please help me out."
The steps below are offered to modify the following work
int findTotal(){
}
Change prototype to:
int FindTotal(char *arr);
count each occurrence of unique element in array (How to reference)
Adapt above reference to use printf and formatting to match your stated output. (How to reference)
So I've got this here:
#include <stdio.h>
char halloString[] = "Ha::ll::o";
char perfumeString[] = "47::11";
char veryLongString[] = "47::11::GHesd::dghsr::bfdr:hfgd46dG";
char *extract (char *input) {somethinghappenshere}
where extract needs to get all characters after the last double ":" of given input:
"o" for halloString
"11" for perfumeString
"bfdr:hfgd46dG" for veryLongString
In short, my issue is finding the length of the string *input points to. As far as I understand it that won't be happening without making something really sketchy.
Am I correct in assuming the length cannot be acquired in a good way?
And if so would it be a horrible idea to do, for example:
char stringToProcessTemp1[50];
char stringToProcessTemp2[50];
char stringToProcess[50];
for (int i = 0; i < 50; i++) {
stringToProcessTemp1[i] = input + i;
}
for (int i = 0; i < 50; i++) {
stringToProcessTemp2[i] = input + i;
}
for (int i = 0; i < 50; i++) {
if (stringToProcessTemp1[i] == stringToProcessTemp2[i]) {
stringToProcessTemp[i] = stringToProcessTemp1[i];
}
}
Later checking where the first empty index is and saving everything before it as the used String as from my very limited experience in C when you go outside of an array you tend to get different outputs every time therefore making the chance both Temp strings match for an extra element directly after the last one of the original string what I'd consider low enough.
It's honestly the only idea I've got right now.
Finding the length of a string is no problem. strlen will do that for you. However, you don't even need that.
You can use the strstr function to find a substring within a string, in this case "::". When you find one, keep looking right after the last one you found until you don't find it anymore, then the last one you found is the one you want. Then you want the substring that starts right after it.
char *extract(char *input)
{
char *last = NULL, *start = input, *curr;
while ((curr == strstr(start, "::")) != NULL) {
last = curr; // keep track of the last "::" found
start = last + 1; // move the starting string to right after the last "::"
// move up 1 instead of 2 in case of ":::"
}
if (last != NULL) {
last +=2; // We found one; move just past the "::"
}
return last;
}
C strings, which are really only an array of characters, are by definition terminated by '\0'. So, for a well formed C string you can always get the length of the string by using strlen().
If, however, your string is not null-terminated, there is no way to determine it's length, and it is not a C string by definition any more, but just an array of characters.
I'm studying C on my own in preparation for my upcoming semester of school and was wondering what I was doing wrong with my code so far.
If Things look weird it is because this is part of a much bigger grab bag of sorting functions I'm creating to get a sense of how to sort numbers,letters,arrays,and the like! I'm basically having some troubles with the manipulation of strings in C currently.
Also, I'm quite limited in my knowledge of C at the moment!
My main Consists of this:
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
int numbers[10];
int size;
int main(void){
setvbuf(stdout,NULL,_IONBF,0); //This is magical code that allows me to input.
int wordNumber;
int lengthOfWord = 50;
printf("How many words do you want to enter: ");
scanf("%i", &wordNumber);
printf("%i\n",wordNumber);
char words[wordNumber][lengthOfWord];
printf("Enter %i words:",wordNumber);
int i;
for(i=0;i<wordNumber+1;i++){ //+1 is because my words[0] is blank.
fgets(&words[i], 50, stdin);
}
for(i=1;i<wordNumber+1;i++){ // Same as the above comment!
printf("%s", words[i]); //prints my words out!
}
alphabetize(words,wordNumber); //I want to sort these arrays with this function.
}
My sorting "method" I am trying to construct is below! This function is seriously flawed, but I'd thought I'd keep it all to show you where my mind was headed when writing this.
void alphabetize(char a[][],int size){ // This wont fly.
size = size+1;
int wordNumber;
int lengthOfWord;
char sortedWords[wordNumber][lengthOfWord]; //In effort for the for loop
int i;
int j;
for(i=1;i<size;i++){ //My effort to copy over this array for manipulation
for(j=1;j<size;j++){
sortedWords[i][j] = a[i][j];
}
}
//This should be kinda what I want when ordering words alphabetically, right?
for(i=1;i<size;i++){
for(j=2;j<size;j++){
if(strcmp(sortedWords[i],sortedWords[j]) > 0){
char* temp = sortedWords[i];
sortedWords[i] = sortedWords[j];
sortedWords[j] = temp;
}
}
}
for(i=1;i<size;i++){
printf("%s, ",sortedWords[i]);
}
}
I guess I also have another question as well...
When I use fgets() it's doing this thing where I get a null word for the first spot of the array. I have had other issues recently trying to scanf() char[] in certain ways specifically spacing my input word variables which "magically" gets rid of the first null space before the character. An example of this is using scanf() to write "Hello" and getting " Hello" or " ""Hello"...
Appreciate any thoughts on this, I've got all summer to study up so this doesn't need to be answered with haste! Also, thank you stack overflow as a whole for being so helpful in the past. This may be my first post, but I have been a frequent visitor for the past couple of years and it's been one of the best places for helpful advice/tips.
You're going to like this - it's a derivation of QSort, adapted to your situation. It may not work quite perfectly for you without a touchup here or there (TEST FIRST!):
void qsort (Strings[], NumberOfItems)
{
char Temp[51]; // Assumes your max string length of 50
int I1 = 0; // Primary index
int I2 = 0; // Index + 1
int NumberOfItems_1 = 0;
bool Swapped = false;
do // Outer loop
{
Swapped = false;
// Decrement our limit
NumberOfItems--;
// Save time not performing this subtraction many times
NumberOfItems_1 = NumberOfItems - 1;
// Repeatedly scan the list
for (I1 = 0; I1 < NumberOfItems_1; I1++)
{
// Save time not performing this addition many times
// I1 points to the current string
// This points to the next string
I2 = I1 + 1;
// If the current string is greater than the next string in the list,
// swap the two strings
if (strcmp(Strings[I1], Strings[I2]) > 0)
{
strcpy (Temp, Strings[I1]);
strcpy (Strings[I1], Strings[I2]);
strcpy (Strings[I2], Temp);
Swapped = true;
}
}
}
while (Swapped); // Break out when we've got nothing left to swap
}
I see a few things wrong with your code off the bat. First, you declare sortedWords as a multidimensional array (since you have sortedWords[wordnumber][lengthofword], but you try to use it with only one index later on.. this doesn't work! Also, your passing of the 2D array is not valid. Check out this post to see the valid ways to pass a 2D array: Passing a 2D array to a C++ function
Function declaration and definition
The function declaration is invalid, as you've found out. You must specify the size of every dimension of the array except the first, so you might write:
void alphabetize(char a[][SOMESIZE], int size)
However, you have a non-constant second dimension (so you're using a VLA or variable length array), which means that you need to pass both sizes to the function, and pass them before you pass the array:
void alphabetize(int size, int length, char a[size][length])
and then invoke it:
alphabetize(wordNumber, lengthOfWords, words);
Of course, you should also declare the function before you try calling it.
There are probably other issues to be addressed, but this is the immediate one that jumps out. For example, you need to use size and length to control the loops in the function. You probably don't need to copy the data into the local array (in which case you don't need the local array). Etc.
You should consider compiling with options such as:
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -Wold-style-declaration -Werror …
Note that note all versions of GCC support all those options, but use as many as are supported.
Input issue
You have:
int i;
for (i = 0; i < wordNumber + 1; i++) { //+1 is because my words[0] is blank.
fgets(&words[i], 50, stdin);
}
You're stepping out of bounds of your array, which potentially wreaks havoc on your code. The first entry is blank because scanf() leaves the newline in the input buffer. You should read to the end of line before going to line-based input:
int c;
while ((c = getchar()) != EOF && c != '\n')
;
You should also check the fgets() returns a non-null pointer; don't continue if it does.