I am trying to calculate the mode or the integer that appears the most for each line.
I get an print two values and then segmentation fault.
for (i = 0; i < count; i++) {
if (array[i]) {
int i, j, k, cnt = 1, p, big;
int b[MAX_NUM] = {0};
printf("count:%d\n", count);
for (i = 1; i <= array[i]; i++) {
for (j = i + 1; j <= array[i]; j++) {
if (array[i] == array[j])
printf("cnt:%d\n", cnt);
cnt++;
}
printf("cnt2:%d\n", cnt);
b[k] = cnt;
k++;
cnt = 1;
}
big = b[k];
p = 1;
for (i = 2; i <= array[i]; i++) {
if (big < b[i]) {
big = b[i];
p = i;
}
}
printf("The element that occurs offen is %d\n", array[p]);
printf("And it has occurred %d times\n", b[p]);
}
}
}
}
}
return 0;
}
EDIT:
See the look here in my code. The values that are printed are the numbers on each line of the file followed by a blank line like this:
1
2
3
4
5
6
5
4
5
14
62
48
14
1
3
5
7
9
123
456
789
1234
5678
34
34
34
34
34
1
1
2
2
2
2
2
3
3
4
4
4
4
5
5
6
7
7
7
1
1
Integers: 9
.....
You redefine i and p in an inner scope where they shadow current definitions. This is obviously unintentional as the for expression looks quite wrong:
if (array[i]) {
int i, j, k=1, cnt = 1, p, big;
// ^
// Redefinition of i.
// You should use a different name for the loop index below
// Same remark for p, it is safer to not redefine local variables
// in inner scopes. Any { starting a block creates a new scope
// in which variables can be defined, or in this case redefined.
...
for (i = 1; i <= array[i]; i++) {
...
for (i = 2; i <= array[i]; i++) {
...
In the same area of the code, you use k without a prior initialization.
The code to compute maximum occurrences can be put into a separate function and simplified this way:
#include <stdio.h>
// get the number of ocurrences of val in array a of size n
int get_number_of_occurrences(int a[], int n, int val) {
int cnt = 0, i;
for (i = 0; i < n; i++) {
if (a[i] == val)
cnt++;
}
return cnt;
}
// return the index for the number that occurs the most
int get_max_occurrence_index(int a[], int n) {
int p = 0, cnt, max = 0, i;
for (i = 0; i < n; i++) {
cnt = get_number_of_occurrences(a, n, a[i]);
if (max < cnt) {
max = cnt;
p = i;
}
}
return p;
}
int main() {
int i, n, a[20], max;
printf("Enter the maximum number of elements\n");
scanf("%d", &n);
printf("Enter the elements\n");
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
i = get_max_occurrence_index(a, n);
max = get_number_of_occurrences(a, n, a[i]);
printf("The element that occurs most oftenly is %d\n", a[i]);
printf("And it has occurred %d times\n", max);
return 0;
}
If you want to use this logic in your original program, you should use it for each line as you read the file instead of at the end where it only applies to the last line. The line parsing code is incorrect too: you take the first digit's ASCII value as the value instead of parsing it with strtol().
Here is a corrected version:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_NUM 1000
#define MAX_LINE_LEN 2048
#define N 100
void fatal(const char *msg) {
printf("%s\n", msg);
exit(1);
}
int main(int argc, char *argv[]) {
FILE *fp;
char filename[100];
char line[MAX_LINE_LEN];
char *p;
int array[MAX_NUM];
int index, count, max;
printf("Please enter the file name: \n");
if (scanf("%99s", filename) != 1) {
fatal("Error in entering file.");
}
if ((fp = fopen(filename, "r")) == NULL) {
fatal("Unable to open the file.");
}
while ((p = fgets(line, MAX_LINE_LEN, fp)) != NULL) {
/* skip white space */
p += strspn(p, " \t\n");
if (*p == '#' || *p == '\0') {
/* ignore comment and blank lines */
continue;
}
/* scan and convert the numbers */
for (count = 0; *p != '\0'; ) {
if (isdigit((unsigned char)*p)) {
array[count++] = strtol(p, &p, 10);
printf("%d\n", array[count]);
} else {
/* skip to next space or end of string */
p += strcspn(p, " \t\n");
}
/* skip white space after the number */
p += strspn(p, " \t\n");
}
index = get_max_occurrence_index(array, count);
max = get_number_of_occurrences(array, count, array[index]);
printf("The element that occurs most often is %d\n", array[index]);
printf("And it has occurred %d times\n", max);
}
fclose(fp);
return 0;
}
Maybe i just can not see through your code, but at no point do i see you loading the actual numbers from your file into any variable or array to work with.
You are loading a line with while ((p = fgets(line, MAX_LINE_LEN, fp)) != NULL) {
Inside that loop, you are breaking this line into tokens to count how many numbers you have.
As far as i can see, array[count]++; is used to count how many numbers are in each line. Using the index as the line number.
You should start by thinking about how to get your data into a usable format
You can start trying to load the values into a 2 dimensional array.
Using the first dimension for the line number and the second for the values.
If you don't understand your code well enough, you should start with more comments
What do you use your difines and variables for.
#define MAX_NUM 1000 //maximum number of lines
int array[MAX_NUM] = {0}; //index refers to line number of file. used to count numbers in each line.
// read file line by line, split every line into tokens to count amount of numbers
while ((p = fgets(line, MAX_LINE_LEN, fp)) != NULL) {
if (count >= MAX_NUM) {
fatal("Array error");
}
if (line[0] != '#') {
p = strtok(line, " ");
while (p != NULL) {
if (isdigit(*p)) {
array[count]++;
}
p = strtok(NULL, " ");
}
}
count++;
//printf("COUNT:%D\n", count);
}
Choosing good variable names in addition would be even better
#define MAX_NUM 1000 -> #define MAX_LINE_NUM 1000
I have no idea about what your variables int i, j, k, cnt = 1, p, big; do.
Give them better names and or comment them. Will not only help you, but your helpers that need to understand what you intend to do with them.
First i thought you needed help with the algorithm for the mode so i wrote this first:
Using very basic stuff to keep it as simple as possible.
Would be cleaner to put it into functions if you know how.
Did not use functions since it seems you do not know completely how to work with them (you should look into that)
This algorithm is doing the following:
Take the first number in the array
Run through the array and everytime you find that number, you increase a counter
Save the number and the count as highest and highestCnt
Repeat with every number in the array and overwrite highest and highestCnt whenever count > highestCnt
When there are multiple number with the highest occurrence it will only remember the number that was counted first. If you want to return all numbers with the highest occurrence, the coude would need to be changed.
Could do something like checking if count == highestCnt and then set something so you know there is no single number with the highest count until you find one with an even higher count.
#include<stdio.h>
#define sizea 100
int main(void) {
int array[sizea] = { 1,3,6,8,3,6,7,4,6,9,0,3,5,12,65,3,76,5,3,54,
1,3,6,89,3,6,7,4,6,9,0,4,5,12,65,3,76,5,3,54,
1,9,6,8,3,45,7,4,6,9,0,89,5,12,65,3,76,5,3,54,
6,3,6,8,3,6,7,4,6,9,0,23,5,12,65,3,76,5,3,54,
1,3,6,90,3,6,7,4,6,9,0,5,5,12,65,3,76,5,3,54 };
int number;
int count = 1;
int highest = 1;
int highestCnt = 1;
int end = sizea - 1; //end defines at what element in the array the loop will end
int j; //j is used to load a number that will be count
int i; //i is used run through the array and compare every number the the one that is being count
for (j = 0; j <= end; j++) {
number = array[j]; // load a number to count
count = 1; // start counting at 1
for (i = j+1; i <= end; i++) {
// if we find the same number again, we increase the counter
// then we load the last element into the current array position
// then we change decrement "end" by 1
// this is like throwing out all the numbers we allready count
// using while instead of if so it will check the last element that was moved to current position as well
// check for i <= end so it doesnt count twice when the last element equals our number
while (array[i] == number && i <= end) {
count++;
array[i] = array[end];
end--;
}
}
// if the count of the number is highers the the previus highest, it's obviously our new highest count.
if (count > highestCnt) {
highest = number;
highestCnt = count;
}
}
printf("number: %i, count: %i", highest, highestCnt);
}
Related
The problem: After the convert_tolower(words) function is completed I want to add a new word in the words array( if the words array has less than 5 words)..But I am getting either errors or unexpected results(e.g some weird characters being printed)...What i thought is shifting the elements of the words array and then work with pointers because I am dealing with strings.But I am having quite some trouble achieving that..Probably the problem is in lines
35-37
How I want the program to behave:
Get 5 words(strings) at most from user input
Take these strings and place them in an array words
Convert the elements of the array to lowercase letters
After the above,ask the user again to enter a new word and pick the position of that word.If the words array already has 5 words then the new word is not added.Else,the new word is added in the position the user chose.(The other words are not deleted,they are just 'shifted').
Also by words[1] I refer to the first word of the words array in its entirety
The code:
#include <stdio.h>
#include <string.h>
#define W 5
#define N 10
void convert_tolower(char matrix[W][N]);
int main() {
int j = 0;
int i = 0;
int len = 0;
char words[W][N] = {{}};
char test[W][N];
char endword[N] = "end";
char newword[N];
int position;
while (scanf("%9s", test), strcmp(test, endword)) {
strcpy(words[i++], test);
j++;
len++;
if (j == W) {
break;
}
}
convert_tolower(words);
printf("Add a new word\n");
scanf("%9s", newword);
printf("\nPick the position\n");
scanf("%d",position);
if (len < W) {
for (i = 0; i < W-1; i++) {
strcpy(words[i], words[i + 1]); /*Shift the words */
words[position] = newword;
}
}
for (i = 0; i < W; i++) {
printf("%s", words[i]);
printf("\n");
}
printf("End of program");
return 0;
}
void convert_tolower(char matrix[W][N]) {
int i;
int j;
for (i = 0; i < W; i++) {
for (j = 0; j < N; j++) {
matrix[i][j] = tolower(matrix[i][j]);
}
}
}
This initialization
char words[W][N] = {{}};
is incorrect in C. If you want to zero initialize the array then just write for example
char words[W][N] = { 0 };
In the condition of the while loop
while (scanf("%9s", test), strcmp(test, endword)) {
there is used the comma operator. Moreover you are using incorrectly the two-dimensional array test instead of a one-dimensional array
It seems you mean
char test[N];
//...
while ( scanf("%9s", test) == 1 && strcmp(test, endword) != 0 ) {
And there are used redundantly too many variables like i, j and len.
The loop could be written simpler like
char test[N];
//...
for ( ; len < W && scanf("%9s", test) == 1 && strcmp(test, endword) != 0; ++len )
{
strcpy(words[len], test);
}
In this call
scanf("%d",position);
there is a typo. You must to write
scanf("%d", &position);
Also you should check whether the entered value of position is in the range [0, len].
For example
position = -1;
printf("\nPick the position\n");
scanf("%d", &position);
if ( len < W && -1 < position && position <= len ) {
Also this for loop
for (i = 0; i < W-1; i++) {
strcpy(words[i], words[i + 1]); /*Shift the words */
words[position] = newword;
}
does not make a sense. And moreover this assignment statement
words[position] = newword;
is invalid. Arrays do not have the assignment operator.
You need to move all strings starting from the specified position to the right.
For example
for ( i = len; i != position; --i )
{
strcpy( words[i], words[i-1] );
}
strcpy( words[position], newword );
++len;
And it seems the function convert_tolower should be called for the result array after inserting a new word. And moreover you need to pass the number of actual words in the array.
convert_tolower(words, len);
The nested loops within the function convert_tolower should look at least the following way
void convert_tolower(char matrix[][N], int n) {
int i;
int j;
for (i = 0; i < n; i++) {
for (j = 0; matrix[i][j] != '\0'; j++) {
matrix[i][j] = tolower(( unsigned char )matrix[i][j]);
}
}
}
The main problem with your code was initially that you declared char *words[W][N], then tried to insert strings into this 2d array of pointers. Sparse use of organizing functions, and variables with large scopes than necessary made it hard to read. I think the best way to help you is to show you a working minimal implementation. Step 4 is not sufficiently specified. insert currently shift. It is not clear what should happen if you insert at position after empty slots, or if insert a position before empty slots and in particular if there are non-empty slots after said position.
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define W 5
#define N 10
void convert(size_t w, size_t n, char list[][n]) {
for(size_t i = 0; i < w; i++) {
for(size_t j = 0; j < n; j++) {
list[i][j] = tolower(list[i][j]);
}
}
}
void insert(size_t w, size_t n, char list[][n], size_t pos, char *word) {
// out out of bounds
if(pos + 1 > w) return;
// shift pos through w - 2 pos
for(size_t i = w - 2; i >= pos; i--) {
strcpy(list[i + 1], list[i]);
if(!i) break;
}
// insert word at pos
strcpy(list[pos], word);
}
void print(size_t w, size_t n, char list[][n]) {
for (size_t i = 0; i < w; i++) {
printf("%u: %s\n", i, list[i]);
}
}
int main() {
char words[W][N] = { "a", "BB", "c" };
convert(W, N, words);
insert(W, N, words, 0, "start");
insert(W, N, words, 2, "mid");
insert(W, N, words, 4, "end");
insert(W, N, words, 5, "error")
print(W, N, words);
return 0;
}
and the output (note: "c" was shifted out as we initially had 3 elements and added 3 new words with valid positions):
0: start
1: a
2: mid
3: bb
4: end
I got a problem of completing the code below.
#include <stdio.h>
void triR(void)
{
int size, repeat;
scanf("%d %d", &size, &repeat);
printf("Hello world\n");
// ...
// Complete this function
// ...
printf("Bye world\n");
}
Example of function excution
The above three are the input values.
I think The first is the minimum size of the number (I do not know why it does not work if I do not enter 1), the middle is the maximum size of the number, and the last is the number of iterations of the input value.
After looking at the example, I created the following code
#include <stdio.h>
#include <stdlib.h>
void triR(void)
{
int size, repeat;
int num;
scanf("%d %d", &size, &repeat);
printf("Hello world\n");
for (int b = 0; b < size; ++b) //b = horizontal line, a = number
{
for (int a = 0; a <= b; ++a)
{
for (num = 1; num <= a; ++num) - failed sentences
{
printf("%d", num);
}
}
printf("\n");
}
for (int k = size; k > 0 ; --k) //k = horizontal line, i = number
{
for (int i = 1; i < k; ++i)
{
{
printf("*"); -Sentences that were successfully run using *
}
}
printf("n");
}
// for (int c =o; ) - sentences tried to make about repeating output value
printf("Bye world\n");
return 0;
}
I know my code looks a lot strange.
I didn't have the confidence to make that code in numbers, so I tried to make it * and convert it.
It succeeded in running by *, but it continues to fail in the part to execute by number.
There is no one to ask for help, but I am afraid that I will not be able to solve it even if I am alone in the weekend. I can not even convert numbers far repeated outputs. I would really appreciate it even if you could give me a hint.
The above code I created(Failed)
Code with *
I'd like to say that even though I managed an implementation, it is definitely neither efficient nor practical. I had to restrict your size variable to digits, as I used ASCII to convert the numbers into characters and couldn't use the itoa() function, since it's not standard.
#include <stdio.h>
#include <stdlib.h>
void triR(void) {
int size, repeat;
scanf("%d %d", &size,&repeat);
printf("Hello world\n");
// string size of n^2+2n-1
char* print_string = malloc((size*size+2*size-1)*sizeof(char));
unsigned int number = 1;
unsigned int incrementer = 1;
while (number < size) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number++;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
while (number > 0) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number--;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
for (int i = 0; i < repeat; i++) {
printf("%s\n", print_string);
}
printf("Bye world\n");
free(print_string);
}
I allocated a char* with the size of size^2+2size-1, as this is the size required for the newline and number characters.
The variables number and incrementer are unsigned and start at 1 as they don't need to go below 1.
I put two while loops with similar code blocks in them:
while (number < size) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number++;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
while (number > 0) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number--;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
The first loop goes up to the size and inserts the characters into the char* in their positions. When the number is done, it increments the incrementer and adds the newline character.
The second loop goes down in number, doing the same things but this time decrementing the number variable. These two variables start at 1, as that's the start of the "pyramid".
*(print_string+i+incrementer-1) = 48+number;
There is a restriction here, in that if you exceed the number 9 your output will print whatever the ASCII representation of 58 is, so if you want to go above 9, you need to change that.
The for loop just prints the final string "repeat" times as wanted. The newline in the printf() function is not necessary, as the final string contains a newline character at the end, I left it in though. The downside of this implementation is that you're using a char* rather than some other sophisticated method.
Dont forget to free the char* when you're done, and don't forget to add user input error-checking.
#include <stdio.h>
#include <stdlib.h>
void clear(FILE *stream)
{
int ch; // read characters from stream till EOF or a newline is reached:
while ((ch = fgetc(stream)) != EOF && ch != '\n');
}
int main(void)
{
int min, max, count;
while (scanf("%d %d %d", &min, &max, &count) != 3 || // repeat till all 3 fields read successfully and
!min || !max || !count || min > max) { // only accept positive numbers as input
fputs("Input error!\n\n", stderr); // and make sure that the max is greater than the min
clear(stdin); // remove everything from stdin before attempting another read for values
}
puts("Hello world\n");
for (int i = 0; i < count; ++i) { // output the triangle count times
for (int row = min; row <= max; ++row) { // count row from min to max
for (int n = min; n <= row; ++n) // print row (row-min) times
printf("%d ", row);
putchar('\n'); // add a newline after every row
}
for (int row = max - 1; row >= min; --row) { // count from max-1 to min
for (int n = min; n <= row; ++n) // same as above: print row (row-min) times
printf("%d ", row);
putchar('\n'); // add a newline after every row
}
putchar('\n'); // add a newline between repetitions
}
puts("Bye world\n");
}
I am self teaching C programming.
I am trying to count number of int present in given string which are separated by space.
exp:
input str = "1 2 11 84384 0 212"
output should be: 1, 2, 11, 84384, 0, 212
total int = 6
When I try. It gives me all the digits as output which make sense since I am not using a right approach here.
I know in python I can use str.split (" ") function which can do my job very quickly.
But I want to try something similar in C. Trying to create my own split method.
#include <stdio.h>
#include <string.h>
void count_get_ints(const char *data) {
int buf[10000];
int cnt = 0, j=0;
for (int i=0; i<strlen(data); i++) {
if (isspace(data[i] == false)
buf[j] = data[i]-'0';
j++;
}
printf("%d", j);
}
// when I check the buffer it includes all the digits of the numbers.
// i.e for my example.
// buf = {1,2,1,1,8,4,3,8,4,0,2,1,2}
// I want buf to be following
// buf = {1,2,11,84384,0,212}
I know this is not a right approach to solve this problem. One way to keep track of prev and dynamically create a memory using number of non space digits encountered.
But I am not sure if that approach helps.
You want to build your number incrementally until you hit a space, then put that into the array. You can do this by multiplying by 10 then adding the next digit each time.
void count_get_ints(const char *data) {
int buf[10000];
int j = 0;
int current_number = 0;
// Move this outside the loop to eliminate recalculating the length each time
int total_length = strlen(data);
for (int i=0; i <= total_length; i++) {
// Go up to 1 character past the length so you
// capture the last number as well
if (i == total_length || isspace(data[i])) {
// Save the number, and reset it
buf[j++] = current_number;
current_number = 0;
}
else {
current_number *= 10;
current_number += data[i] - '0';
}
}
}
I think strtok will provide a cleaner solution, unless you really want to iterate over every char in the string. It has been a while since I did C, so please excuse any errors in the code below, hopefully it will give you the right idea.
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[19] = "1 2 11 84384 0 212";
const char s[2] = " ";
char *token;
int total;
total = 0;
token = strtok(str, s);
while (token != NULL) {
printf("%s\n", token);
total += atoi(token);
token = strtok(NULL, s);
}
printf("%d\n", total);
return 0;
}
You can check the ascii value of each character by doing c-'0'. If it's between [0,9], then it's an integer. By having a state variable, when you're inside an integer by checking if a given character is a number of space, you can keep track of the count by ignoring white space. Plus you don't need a buffer, what happens if data is larger than 10,000, and you write pass the end of the buffer?, undefined behavior will happen. This solution doesn't require a buffer.
Edit, the solution now prints the integers that are in the string
void count_get_ints(const char *data) {
int count = 0;
int state = 0;
int start = 0;
int end = 0;
for(int i = 0; i<strlen(data); i++){
int ascii = data[i]-'0';
if(ascii >= 0 && ascii <= 9){
if(state == 0){
start = i;
}
state = 1;
}else{
//Detected a whitespace
if(state == 1){
count++;
state = 0;
end = i;
//Print the integer from the start to end spot in data
for(int j = start; j<end; j++){
printf("%c",data[j]);
}
printf(" ");
}
}
}
//Check end
if(state == 1){
count++;
for(int j = start; j<strlen(data); j++){
printf("%c",data[j]);
}
printf(" ");
}
printf("Number of integers %d\n",count);
}
I believe the standard way of doing this would be using sscanf using the %n format specifier to keep track of how much of the string is read.
You can start with a large array to read into -
int array[100];
Then you can keep reading integers from the string till you can't read anymore or you are done reading 100.
int total = 0;
int cont = 0;
int ret = 1;
while(ret == 1 && total < 100) {
ret = sscanf(input, "%d%n", &array[total++], &cont);
input += cont;
}
total--;
printf("Total read = %d\n", total);
and array contains all the numbers read.
Here is the DEMO
Example using strtol
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>
int count_get_ints(int output[], int output_size, const char *input) {
const char *p = input;
int cnt;
for(cnt = 0; cnt < output_size && *p; ++cnt){
char *endp;
long n;
errno = 0;
n = strtol(p, &endp, 10);
if(errno == 0 && (isspace((unsigned char)*endp) || !*endp) && INT_MIN <= n && n <= INT_MAX){
output[cnt] = n;
while(isspace((unsigned char)*endp))
++endp;//skip spaces
p = endp;//next parse point
} else {
fprintf(stderr, "invalid input '%s' in %s\n", p, __func__);
break;
}
}
return cnt;
}
int main(void) {
const char *input = "1 2 11 84384 0 212";
int data[10000];
int n = sizeof(data)/sizeof(*data);//number of elements of data
n = count_get_ints(data, n, input);
for(int i = 0; i < n; ++i){
if(i)
printf(", ");
printf("%d", data[i]);
}
puts("");
}
Assuming you don't have any non-numbers in your string, you can just count the number of spaces + 1 to find the number of integers in the string like so in this pseudo code:
for(i = 0; i < length of string; i++) {
if (string x[i] == " ") {
Add y to the list of strings
string y = "";
counter++;
}
string y += string x[i]
}
numberOfIntegers = counter + 1;
Also, this reads the data between the white spaces. Keep in mind this is pseudo code, so the syntax is different.
I have a file named sample.txt which contains 1000 integers(both positive and negative numbers). First I copied the file into an array of size 1000 (say a).
My aim is to locate the largest sub array in a and find the sum of elements in it.
An array is a sub array if it's consecutive elements are in increasing order. For example in the array {12,23,3,1,-56,2,4,6,45,49,1,2,-10} the sub array is {-56,2,4,6,45,49}.
Then I need to calculate the sum of elements of this sub array.
Given below is my attempt to solve the problem using a C program.
I'm a non-CS major just finished C programming in this semester. Your help would be very much appreciated.
int sum(int a[],int i,int temp)
{
int sum=0,j;
for(j=i;j<i+temp;j++)
sum+=a[j];
printf("Sum = %d", sum);
return 0;
}
int main()
{
FILE *f1;
int a[1000],b[900];
int number,i=-1,counter=0,temp=1,check=1,j;
f1 = fopen("sample.txt","r");
while (!feof (f1) && fscanf (f1, "%d", &number) && i++ < 1000 )// copying the file to an array
a[i] = number;
fclose(f1);
for(i=1;i<1000;i++)
{
if(a[i-1]<a[i])
counter++;
else
{
if(counter>temp)
temp=counter;
counter=0;
}
}
temp++;
printf("Temp= %d", temp); // the length of the largest sub array whose elements are in increasing order
sum(a,i,temp);
return 0;
}
Just a general advice, in order to prevent your program from crashing:
Change this:
while (!feof (f1) && fscanf (f1, "%d", &number) && i++ < 1000 )
a[i] = number;
To this:
while (!feof (f1) && fscanf (f1, "%d", &number) && i < 1000 )
a[i++] = number;
Well, I come from C++ but maybe I can help..you could try this :
for(i=1;i<=1000;i++)
{
if(a[i]<a[i+1])
counter++;
I introduced a new variable temp_index which will hold the starting index of the largest sub-array and used j to store the starting index in the loop.
Try this
if(a[i-1]<a[i])
{
if (counter == 0) { j = i }
counter++;
}
else
{
if(counter>temp) {
temp_index = j;
temp=counter;
}
counter=0;
}
}
temp++;
printf("Temp= %d", temp); // the length of the largest sub array whose elements are in increasing order
sum(a,temp_index,temp)
to locate the largest sub array in a
"To locate the largest", I suppose you mean longest sub-array.
Anyway, here is an implementation (it works for your test input):
int longest_increasing(int array[], int length, int *start, int *end)
{
int pos, curr_pos;
*start = 1;
*end = 0;
curr_pos = 0;
while (curr_pos + 1 < length) {
while (curr_pos+1 < length && array[curr_pos] >= array[curr_pos+1])
curr_pos++;
for (pos = curr_pos; pos+1 < length && array[pos] < array[pos+1]; pos++)
;
if (*end - *start < pos - curr_pos) {
*start = curr_pos;
*end = pos;
}
curr_pos = pos+1;
}
if (*start < *end)
return 1;
else
return 0;
}
Suppose n numbers are to be input in a single line without any spaces given the condition that these numbers are subject to the condition that they lie between 1 and 10.
Say n is 6 , then let the input be like "239435"
then if I have an array in which I am storing these numbers then I should get
array[0]=2
array[1]=3
array[2]=9
array[3]=4
array[4]=3
I can get the above result by using array[0]=(input/10^n) and then the next digit
but is there a simpler way to do it?
Just subtract the ASCII code of 0 for each digit and you get the value of it.
char *s = "239435"
int l = strlen(s);
int *array = malloc(sizeof(int)*l);
int i;
for(i = 0; i < l; i++)
array[i] = s[i]-'0';
update
Assuming that 0 is not a valid input and only numbers between 1-10 are allowed:
char *s = "239435"
int l = strlen(s);
int *array = malloc(sizeof(int)*l);
int i = 0;
while(*s != 0)
{
if(!isdigit(*s))
{
// error, the user entered something else
}
int v = array[i] = *s -'0';
// If the digit is '0' it should have been '10' and the previous number
// has to be adjusted, as it would be '1'. The '0' characater is skipped.
if(v == 0)
{
if(i == 0)
{
// Error, first digit was '0'
}
// Check if an input was something like '23407'
if(array[i-1] != 1)
{
// Error, invalid number
}
array[i-1] = 10;
}
else
array[i] = v;
s++;
}
E.g.
int a[6];
printf(">");
scanf("%1d%1d%1d%1d%1d%1d", a,a+1,a+2,a+3,a+4,a+5);
printf("%d,%d,%d,%d,%d,%d\n", a[0],a[1],a[2],a[3],a[4],a[5]);
result:
>239435
2,3,9,4,3,5
You can use a string to take the input and then check each position and extact them and store in an array. You need to check for the numeric value in each location explicitly, as you are accepting the input as a string. For integers taken input as string, there's no gurantee that the input is pure numeric and if it is not, things can go wild.
check this code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char ipstring[64];
int arr[64];
int count, len = 0;
printf("Enter the numbersi[not more than 64 numbers]\n");
scanf("%s", ipstring);
len = strlen(ipstring);
for (count = 0; count < len ; count++)
{
if (('0'<= ipstring[count]) && (ipstring[count] <= '9'))
{
arr[count] = ipstring[count] - '0';
}
else
{
printf("Invalid input detectde in position %d of %s\n", count+1, ipstring );
exit(-1);
}
}
//display
for (count = 0; count < len ; count++)
{
printf("arr[%d] = %d\n", count, arr[count]);
}
return 0;
}