I am working on a program that uses file redirection to read in a file, read one character per line until I reach a '0', store the characters in an array , and sort that array (from largest to smallest). Anyway, I really only need help with reading the characters until the zero shows up. Below is the text file that I am reading in:
f
k
s
j
p
a
v
r
t
u
h
m
g
e
b
y
n
z
w
l
i
x
q
c
o
d
0
Below is the code I have so far:
int main(void)
{
int i=0;
char array[100];
while(fscanf(stdin, "%c", &array[i]) && array[i]!='0')
{
i++;
}
int N = (sizeof(array)/sizeof(array[0]));
for(i=0;i<N;i++)
{
printf("%c", array[i]);
}
return(0);
}
When I run this program, it prints out every line of the file, including the zero. It also prints out some really weird characters after the zero (using gcc compiler). What am I doing wrong?
You need to set N to the value of i, currently it will always be 100
You use i to keep track of how many items you've read, but then you overwrite the value of i in your loop and print out all 100 elements, whether you stored something there or not.
Use different variable for counting the element than you do for looping, and use the count as your loop limit.
int count=0;
char array[100];
while(fscanf(stdin, "%c", &array[count]) && array[count]!='0')
{
count++;
}
for(i=0;i<count;i++)
{
printf("%c", array[i]);
}
fscanf needs to skip the separator (enter or space), else it will be incorporated into your list. Adding a space fixes that.
#include <stdio.h>
#include <stdlib.h>
int sort (const void *a,const void *b)
{
return ((int)*((unsigned char *)a)) - ((int)*((unsigned char *)b));
}
int main (void)
{
unsigned char array[100],i=0;
while (fscanf(stdin," %c", &array[i]) && array[i] != '0')
i++;
qsort (array,i,1,sort);
while (i)
printf ("%c\n", array[--i]);
}
It may seem this program sorts the wrong way around but the printing loop also happens to print in reverse, so that solves it neatly. As the array is unsigned char, the sort routine casts this to int to prevent possible overflow.
Related
#include <stdio.h>
#include <string.h>
int main(void)
{
char alpha[26] = { '0' };
char nl;
while (alpha != '0'){
scanf("%c", &alpha);
scanf("%c", &nl);
printf("the character is %c\n", alpha);
}
int i, j, size;
for (i=0;i<size;i++){
for (j=i;j<size;j++){
if (alpha[i]<alpha[j]){
Swap(&alpha[i], &alpha[j]);
}
}
}
printf("%s", alpha);
return 0;
}
I'm getting an error "comparison between pointer and integer" in my while loop. I'm wanting to read in each letter of the alphabet from a text file and stop when it reaches a "0" at the end of the list. It's then going to sort alphabetically starting with z,y,x.. etc. How else could I write this so it stops at "0" without using an integer?
Thanks for the help
alpha [26] is an array of 26 chars, with your while loop you always overwrite the first element of the array (scanf("%c", &alpha); overwrites the first element of alpha in every iteration of the loop ) , the entire code will not work. to access the elements of the array you can either use pointers or indexes, indexes are easier, try a for loop
int i;
for (i = 0; i<26 ; i++)
{
if(alpha[i] != '0')
{
scanf("%c", &alpha[i]);
printf("the character is %c\n", alpha[i]);
}
}
C: scanf to array
for using pointers to access array see Can i use pointer in scanf to take input in an array?
This seemed like a simple idea when I decided to try it out, but know it's driving me nuts.
I can reverse a whole string, but now I'm trying to reverse individual parts of a string.
Example:
"pizza is amazing" to "azzip si amazing"
Basically my program should reverse a string from point a to b, treating any words within it separately. My logic appears right (at least to me), but obviously something is wrong because my output is just the first word "pizza".
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *reverse(char *a, int i, int j){ //reverse the words
char temp;
while(i<j){
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
return a;
}
char *words(char *a, int i, int j){ // identify if there are any words from a-b
int count = i;
while(i<j){
if(a[i] == ' '){ // a space signifies the end of a word
reverse(a , i-count, i);
count = 0; //reset count for next word
}
i++;
count++;
}
return a;
}
int main(){
char a[50];
char *a2;
printf("Enter a string:\n); //string input
scanf("%s", a);
int strlength = strlen(a) + 1;
a2 = (char *)malloc(strlength*sizeof(char));
strcpy( a2, a);
printf("Reversed string:\n%s", words(a, 0, 4)); // create a-b range
return 0;
}
I realize my problem is most likely within words(). I am out of ideas.
Problem 1:
You should be more careful naming variables, understandable and meaningful names help the programmer and others reading your code. Keep in mind this is extremely important.
Problem 2:
When you pass the parameter %s to scanf(), it will read subsequent characters until a whitespace is found (whitespace characters are considered to be blank, newline and tab).
You can use scanf("%[^\n]", a) to read all characters until a newline is found.
For further reference on scanf(), take a look here.
Problem 3:
Take a look at the words() function, you're not storing a base index (from where to start reversing). The call to reverse() is telling it to reverse a single character (nothing changes).
You didn't specified if a whole word must be inside the range in order to be reversed or even if it is on the edge (ex: half in, half out). I'll assume the whole word must be inside the range, check out this modified version of the words() function:
char *words(char *str, int fromIndex, int toIndex){
int i = fromIndex;
int wordStartingIndex = fromIndex;
/*
It is necessary to expand the final index by one in order
get words bounded by the specified range. (ex: pizza (0, 4)).
*/
toIndex += 1;
/* Loop through the string. */
while(i <= toIndex){
if(str[i] == ' ' || str[i] == '\0' || str[i] == '\n'){
reverse(str, wordStartingIndex, i-1);
wordStartingIndex = (i + 1);
}
i++;
}
return str;
}
This should get you started. The function it is not perfect, you'll need to modify it in order to handle some special cases, such as the one I've mentioned.
I'm trying to write a C program which eats a string of a priori bounded length and returns 1 if it's a palindrome and 0 otherwise. We may assume the input consists of lower case letters.
This is a part of a first course in programming, so I have no experience.
Here's my attempt. As soon as I try to build/run it on CodeBlocks, the program shuts down. It's a shame because I thought I did pretty well.
#include <stdio.h>
#define MaxLength 50
int palindrome(char *a,int size) /* checks if palindrome or not */
{
int c=0;
for(int i=0;i<size/2;i++) /* for every spot up to the middle */
{
if (*(a+i)!=*(a+size-i-1)) /* the palindrome symmetry condition */
{
c++;
}
}
if (c==0)
{
return 1; /*is palindrome*/
}
else
return 0; /*is not palindrome*/
}
int main()
{
char A[MaxLength]; /*array to contain the string*/
char *a=&A[0]; /*pointer to the array*/
int i=0; /*will count the length of the string*/
int temp;
while ((temp=getchar())!='\n' && temp != EOF) /*loop to read input into the array*/
{
A[i]=temp;
i++;
}
if (palindrome(a,i)==1)
printf("1");
else
printf("0");
return 0;
}
Remark. I'm going to sleep now, so I will not be responsive for a few hours.
Your approach is ok, though you have a number of small errors. First,#define MaxLength=50 should be #define MaxLength 50 (the text to replace, space, then its replacement).
You should also provide a prototype for your palindrome() function before main():
int palindrome(char *a,int size);
...or just move the whole palindrome() function above main(). Either a prototype or the actual function definition should appear before any calls to the function happen.
Next issue is that you're looking for a null character at the end of the input string. C strings are usually null terminated, but the lines coming from the console aren't (if there's a terminator it would be added by your program when it decides to end the string) -- you should probably check for a newline instead (and ideally, for errors as well). So instead of
while ((temp=getchar())!='\0')
try
while ((temp=getchar())!='\n' && temp != EOF)
When you print your results in main(), you should have a newline at the end, eg. printf("1\n"); instead of printf("1");, to ensure the output buffer gets flushed so you can see the output as well as to end that output line.
Then in your palindrome() function, your for loop sytax is wrong -- the three parts should be separated with semicolons, not commas. So change:
for(int i=0,i<size/2,i++)
...to:
for(int i=0; i<size/2; i++)
You also have an extra closing brace for the loop body to remove.
After fixing all that, it seems to work...
This directive
#define MaxLength=50
is invalid. There should be
#define MaxLength 50
Change the loop in main the following way
int temp;
^^^
while ( i < MaxLength && ( temp = getchar () )!= EOF && temp != '\n' )
{
A[i] = temp;
i++;
}
Otherwise if to use the original loop you have to place the zero into the buffer directly using the alt key and the numeric keypad.
The function itself can be written simpler
int palindrome( const char *a, int size) /* checks if palindrome or not */
{
int i = 0;
while ( i < size / 2 && *( a + i ) == *( a + size - i - 1 ) ) ++i; {
return i == size / 2;
}
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.
These are the directions:
Read characters from standard input until EOF (the end-of-file mark) is read. Do not prompt the user to enter text - just read data as soon as the program starts.
Keep a running count of each different character encountered in the input, and keep count of the total number of characters input (excluding EOF).
I know I have to store the values in an array somehow using the malloc() function. I have to organize each character entered by keeping count of how many times that particular character was entered.
Thanks for the help!
Actually, since you are reading from standard input, there are at most 256 different possibilities. (You read in a char). Since that's the case, you could just statically allocate 256 integers for counting. int charCount[256]; Just initialize each value to 0, then increment each time a match is input.
Alternatively, if you must have malloc, then:
// This code isn't exactly what I'd turn in for homework - just a starting
// point, and non-tested besides.
int* charCount = (int*) malloc(sizeof(int) * 256); // Allocate 256.
for (int i = 0; i < 256; i++) charCount[i] = 0; // Initialize to 0.
// Counting and character input go here, in a loop.
int inputChar;
// Read in inputChar with a call to getChar(). Then:
charCount[inputChar]++; // Increment user's input value.
// Provide your output.
free(charCount); // Release your memory.
Here is a possible solution:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
int count[256] = {0};
char *l, *lp;
while (scanf(" %ms", &l) != EOF) {
for (lp = l; *lp; lp++)
count[(int)*lp]++;
free(l);
}
for (int i = 0; i < 256; i++) {
if (isprint(i) && count[i])
printf("%c: %d\n", i, count[i]);
}
exit(EXIT_SUCCESS);
}
Compile:
c99 t.c
Run:
$ ./a.out
abc
ijk
abc
<-- Ctrl-D (Unix-like) or Ctrl-Z (Windows) for EOF
a: 2
b: 2
c: 2
i: 1
j: 1
k: 1