Reading file using fscanf is not working in c? - c

int main(int argc, char **argv) {
char *input = "input.txt";
int *account;
char **name;
float *balance;
int count;
int check;
if (argc < 4 || argc > 4) {
printf("Insufficient arguments. Check your command line arguments\n");
return 1;
}
count = atoi(*(argv + 2));
name = malloc(sizeof(char) * 20 * count);
account = malloc(sizeof(int) * count);
balance = malloc(sizeof(float) * count);
check = load_data(input, name, account, balance, count);
if (check == 0) {
printf("File cannot be open\n");
}
print_data(name, account, balance, count);
free(name);
return 0;
}
//load data from input file the according arrays
int load_data(char *input, char **name, int *acct, float *amt, int n) {
int *a = acct;
float *b = amt;
FILE *file = fopen("input.txt", "r");
int i;
if (file == NULL) {
return 0;
} else {
for (i = 0; i < 9; i++, acct++, amt++) {
fscanf(file, "%s %d %f", *(name + i), acct, amt);
}
}
fclose(file);
acct = a; //return pointer to original position
amt = b;
return 1;
}
//print data from arrays
void print_data(char **name, int *acct, float *amt, int n) {
int i;
for (i = 0; i < n; i++) {
printf("%-10s%-13s%s\n", "Name", "Account No.", "Amount");
printf("%-10s%-13d%7.2f\n", *(name + i), *(acct + i), *(amt + i));
}
}
I have this load_data function that suppose to read from a file and store the data values in different pointers, but for some reason when I print out using print_data function, the pointer contain all null and 0? (Please answer using pointers arithmetic and not array)

I expect that you have not properly prepared the arrays before calling the function... the below main function will work with your code:
int main(int argc, char* argv[]) {
int n = 10;
char ** name = malloc(n * sizeof(char*));
int* acct = malloc(n * sizeof(int));
float* amt = malloc(n * sizeof(float));
for (int i = 0; i < n; i++) {
// this is allocating some space for each line
// this is quite bad you should range check.
name[i] = malloc(256);
}
load_data("", name, acct, amt, n);
print_data(name, acct, amt, n);
// TODO: free everything
}
in load_data: a and b are not required and as amt and acct are "passed by value" there is no need to restore their values at the end of your function. That is to say that the values in all your arguments will be discarded when this function returns only the values that are "pointed to" are updated.
Example input.txt file:
Adam 1 900.9
Daniel 2 800.8
Joe 3 700.7
Foo 4 600.6
Bar 5 500.5
Alice 6 400.4
Bob 7 300.3
Nick 8 200.2
Eve 9 100.1
After altering your code slightly (see below) the above input file does work, here is the output I get:
$ ./test 5 5 5
Name Account No. Amount
Adam 1 900.90
Name Account No. Amount
Daniel 2 800.80
Name Account No. Amount
Joe 3 700.70
Name Account No. Amount
Foo 4 600.60
Name Account No. Amount
Bar 5 500.50
Updated main function based on the one you provided in the question:
int main(int argc, char **argv) {
char *input = "input.txt";
int *account;
char **name;
float *balance;
int count;
int check;
int i;
if (argc < 4 || argc > 4) {
printf("Insufficient arguments. Check your command line arguments\n");
return 1;
}
count = atoi(*(argv + 2));
name = malloc(sizeof(char *) * count);
for (i = 0; i < count; i ++) {
*(name+i) = malloc(20);
}
account = malloc(sizeof(int) * count);
balance = malloc(sizeof(float) * count);
check = load_data(input, name, account, balance, count);
if (check == 0) {
printf("File cannot be open\n");
}
print_data(name, account, balance, count);
free(balance);
free(account);
for (i = 0; i < count; i++) {
free(*(name+i));
}
free(name);
return 0;
}
... also in load_data I changed i < 9 to i < n.

Related

Why do I get a segmentation fault here

Excuse me for the sloppy code, I am still a beginner. But after putting a long time into this programming question I got from my Uni I don't know where to turn.
The question itself is: we need to read from the "staedte.csv" (which displays the population and cities of German states) and then return an array of strings with the strings formatted like this: The city ***** has a population of ****.
You are supposed to pass in 2 arguments into the cli: the number 100 and the state you want to check the cities and population for: example Bayern (Bavaria).
My plan was to make a 2d array. First I would dynamically allocate the memory for the first one by making a for loop and iterating over the original csv to check how many states in the csv = the state from the arguments. Then I would make a dynamic array using the amount of states in the csv matching. Then I would iterate (with for loop) over the list of matching states and then first check the length of the formatted string then: The city ***** has a population of ****., then allocate that memory and store the pointer to that info in the previously created array. Then I try to print the first item of that array, meaning the pointer.
I checked and there are 8 elements in the csv with Bavaria as their state, but in the for loop
for (j = 0; j < 8; j++)
if j is larger than 4 then I Get a segmentation fault even though the space is supposed to be allocated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "input3.h"
/* Die Konstanten:
* int MAX_LAENGE_STR - die maximale String Länge
* int MAX_LAENGE_ARR - die maximale Array Länge
* sind input3.c auf jeweils 255 und 100 definiert
*/
int main(int argc, char **argv)
{
if (argc < 3)
{
printf("Aufruf: %s <anzahl> <bundesland>\n", argv[0]);
printf("Beispiel: %s 100 Bayern\n", argv[0]);
printf("Klein-/Großschreibung beachten!\n");
exit(1);
}
// int anzahl = atoi(argv[1]);
char *bundesland = argv[2];
// Statisch allokierter Speicher
char staedte[MAX_LAENGE_ARR][MAX_LAENGE_STR];
char laender[MAX_LAENGE_ARR][MAX_LAENGE_STR];
int bewohner[MAX_LAENGE_ARR];
read_file("staedte.csv", staedte, laender, bewohner);
// printf("%s %s", bundesland, laender[5]);
int CityCounter = 0;
int CopyCounter = 0;
int *CityArray;
CityArray = (int *)malloc(0);
for (int i = 0; i < MAX_LAENGE_ARR; i++)
{
if (strncmp(laender[i], bundesland, strnlen(bundesland, 10)) == 0)
{
CityArray = realloc(CityArray, sizeof(CityArray) + sizeof(int) * 1);
CityArray[CityCounter] = i;
CityCounter++;
}
}
// printf("%d", CityCounter);
char **string = (char **)malloc(CityCounter * sizeof(int));
int j;
printf("%d", (int)sizeof(CityArray));
int numOfCities = (int)sizeof(CityArray);
for (j = 0; j < 8; j++)
{
char buffer[100];
size_t size = snprintf(buffer, 50, "Die Stadt %s hat %d Einwohner.\n", staedte[CityArray[j]], bewohner[CityArray[j]]);
string[j] = malloc(sizeof(char) * size);
// string[j][size] = "\0";
strncpy(string[j], buffer, size);
}
// printf("%s", string[2]);
for (int i = 0; i < numOfCities; i++)
{
printf("%s", string[i]);
}
// write_file(string, sizeof(string));
free(string);
}
this is the code I wrote.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "input3.h"
int MAX_LAENGE_STR = 255;
int MAX_LAENGE_ARR = 100;
void write_file(char *result[], int len)
{
FILE *fp = fopen("resultat.txt", "w");
if (fp == NULL)
{
perror("resultat.txt");
exit(1);
}
for (int i = 0; i < len; i++)
{
fprintf(fp, "%s\n", result[i]);
}
fclose(fp);
}
int read_file(char *dateiname, char staedte[][MAX_LAENGE_STR], char laender[][MAX_LAENGE_STR], int bewohner[])
{
FILE *fp = fopen(dateiname, "r");
if (fp == NULL)
{
perror(dateiname);
exit(1);
}
char stadt[MAX_LAENGE_STR];
char land[MAX_LAENGE_STR];
int anzahl;
int i = 0;
int len;
while (fscanf(fp, "\"%[^\"]\";\"%[^\"]\";%d\n", stadt, land, &anzahl) != EOF)
{
if (i >= MAX_LAENGE_ARR)
{
printf("ERROR: Die Datei ist größer als erwartet!");
return i;
}
len = strlen(stadt) + 1;
strncpy(staedte[i], stadt, len - 1);
staedte[i][len - 1] = '\0';
len = strlen(land) + 1;
strncpy(laender[i], land, len - 1);
laender[i][len - 1] = '\0';
bewohner[i] = anzahl;
i++;
}
fclose(fp);
return i;
}
extern int MAX_LAENGE_ARR;
extern int MAX_LAENGE_STR;
void write_file(char *result[], int len);
int read_file(char *dateiname, char staedte[][MAX_LAENGE_STR], char laender[][MAX_LAENGE_STR], int bewohner []);
This code was supplied by our Uni but it should be correct.
So I changed the
char **string = (char **)malloc(CityCounter * sizeof(int)); to char
**string = (char *)malloc(CityCounter * sizeof(char)); and now I don't get null.
But if I once again change the
for (j = 0; j < 4; j++) {}
and modify the j larger then 4 then I get a bus error

Sort ints from a txt file

I need to sort ints from a file in ascending order and print them to the standard output. I can't modify the structure of the file.
The txt file looks like this:
41
65
68
35
51
...(one number in a row)
My program works just fine for small files, but I have to optomize it for larger files (like 3 million numbers) using malloc, but don't know exactly where and how. I'd like to ask for help in this. (I'm a beginner)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER 100000
int sort(int size, int arr[])
{
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int swap = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = swap;
}
}
}
}
int main(int argc, char *argv[])
{
char *filename = argv[1];
char s[20];
if (argc == 1)
{
fprintf(stderr, "Error! Input then name of a .txt file\n");
exit(1);
}
FILE *fp = fopen(filename, "r");
if (fp == NULL)
{
fprintf(stderr, "Error! Can't open %s\n", filename);
exit(1);
}
int arr[BUFFER];
int i = 0;
int size = 0;
while ((fgets(s, BUFFER, fp)) != NULL)
{
s[strlen(s) - 1] = '\0';
arr[i] = atoi(s);
++i;
++size;
}
fclose(fp);
sort(size, arr);
for (int i = 0; i < size; ++i)
{
printf("%d\n", arr[i]);
}
return 0;
}
Your program could look like this:
#include <stdlib.h>
#include <stdio.h>
static int numcompar(const void *a, const void *b) {
const int *x = a;
const int *y = b;
// it is tempting to return *x - *y; but undefined behavior lurks
return *x < *y ? -1 : *x == *y ? 0 : 1;
}
int main(int argc, char *argv[]) {
if (argc < 2) {
// TODO: handle error
abort();
}
char *filename = argv[1];
// open the file
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
abort();
}
// this will be our array
// note realloc(NULL is equal to malloc()
int *arr = NULL;
size_t arrcnt = 0;
// note - I am using fscanf for simplicity
int temp = 0;
while (fscanf(fp, "%d", &temp) == 1) {
// note - reallocating the space each number for the next number
void *tmp = realloc(arr, sizeof(*arr) * (arrcnt + 1));
if (tmp == NULL) {
free(arr);
fclose(fp);
abort();
}
arr = tmp;
// finally assignment
arr[arrcnt] = temp;
arrcnt++;
}
fclose(fp);
// writing sorting algorithms is boring
qsort(arr, arrcnt, sizeof(*arr), numcompar);
for (size_t i = 0; i < arrcnt; ++i) {
printf("%d\n", arr[i]);
}
free(arr);
}
Note that reallocating for one int at a time is inefficient - realloc is usually a costly function. The next step would be to keep the number of the size of the array and "used" (assigned to) elements of the array separately and reallocate the array by a ratio greater then 1. There are voices that prefer to use the golden ratio number in such cases.
To read an undetermined number of entries from the input file, you can allocate and reallocate an array using realloc() as more entries are read. For better performance it is recommended to increase the allocated size by a multiple instead of increasing linearly, especially one entry at a time.
Your sorting routine is inappropriate for large arrays: insertion sort has quadratic time complexity, so it might take a long time for 3 million items, unless they are already sorted. Use qsort() with a simple comparison function for this.
Here is a modified program:
#include <stdio.h>
#include <stdlib.h>
static int compare_int(const void *pa, const void *pb) {
int a = *(const int *)pa;
int b = *(const int *)pb;
// return -1 if a < b, 0 if a == b and +1 if a > b
return (a > b) - (a < b);
}
int main(int argc, char *argv[]) {
if (argc == 1) {
fprintf(stderr, "Error! Input then name of a .txt file\n");
exit(1);
}
char *filename = argv[1];
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Error! Can't open %s\n", filename);
exit(1);
}
char buf[80];
size_t n = 0, size = 0;
int *array = NULL;
/* read the numbers */
while (fgets(buf, sizeof buf, fp)) {
if (n == size) {
/* increase size by at least 1.625 */
size_t newsize = size + size / 2 + size / 8 + 32;
int *newarray = realloc(array, newsize * sizeof(*array));
if (newarray == NULL) {
printf("cannot allocate space for %zu numbers\n", newsize);
free(array);
fclose(fp);
exit(1);
}
array = newarray;
size = newsize;
}
array[n++] = strtol(buf, NULL, 10);
}
fclose(fp);
/* sort the array */
qsort(array, n, sizeof(*array), compare_int);
for (size_t i = 0; i < n; i++) {
printf("%d\n", array[i]);
}
free(array);
return 0;
}

Create 2-D Array and Set Values

I am trying to write a C program that generates R files that solve systems of linear equations. In main, I have six nested for loops to get every iteration of where the coefficients are integers 0 - 9:
ax + by + c = dx + ey + f
a_2x + b_2y + c_2 = d_2x + e_2y + f
Each equation is a array of 6 integer coefficients. I set the values of the coefficients in my main function before passing it to generateContentForSystems.
However, my print statement returns:
value of numx:-000-0 value of numy:000-0 value of numz:00-0 value of numx_2:0-0 value of numy_2:-0 value of numz_2:0
I believe this is because of bad pointer arithmetic. I am now trying to and from a pointer to an array (in main) and have an array of arrays.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "scaffold.c"
void * generateContentForSystems(int * row1, int * row2) {
static int index = 0;
int x = row1[0] - row1[3];
int y = row1[1] - row1[4];
int z = row1[5] - row1[2];
int x_2 = row2[0] - row2[3];
int y_2 = row2[1] - row2[4];
int z_2 = row2[5] - row2[2];
int prod1 = x * y_2;
int prod2 = x_2 * y;
int determinant = prod1 - prod2;
if (determinant != 0) {
printf("the value of determinant: %d", determinant);
char * error1;
char Q[1000];
strcpy(Q, "emake <- function(){\noptions(\"warn\"=-1)\ne <- 0\nfor (n in 0:2000){\ne <- e+ 1/(factorial(n))\n}\nreturn(e)\n}\ne <- emake()\n");
char numx[1];
char numy[1];
char numz[1];
char numx_2[1];
char numy_2[1];
char numz_2[1];
sprintf(numx, "%d", x);
sprintf(numy, "%d", y);
sprintf(numz, "%d", z);
sprintf(numx_2, "%d", x_2);
sprintf(numy_2, "%d", y_2);
sprintf(numz_2, "%d", z_2);
//debug:
printf("value of numx:%s value of numy:%s value of numz:%s value of numx_2:%s value of numy_2:%s value of numz_2:%s", numx, numy, numz, numx_2, numy_2, numz_2);
strcat(Q, "A = array(c(");
strcat(Q, numx);
strcat(Q, ", ");
strcat(Q, numx_2);
strcat(Q, ", ");
strcat(Q, numy);
strcat(Q, ", ");
strcat(Q, numy_2);
strcat(Q, "), dim = c(2,2,1))\n");
strcat(Q, "b = c(");
strcat(Q, numz);
strcat(Q, ", ");
strcat(Q, numz_2);
strcat(Q, ")\n");
strcat(Q, "solve(A[,,1],b)\n");
char filename[100];
char snum[5];
itoa(index, snum);
index++;
strcpy(filename, "practice/");
strcat(filename, snum);
strcat(filename, ".R");
FILE * F = fopen(filename, "w");
fputs(Q, F);
fclose(F);
char path[1024];
char command[300];
strcpy(command, "Rscript ");
strcat(command, "practice/");
debug("After Rscript formation");
strcat(command, snum);
strcat(command, ".R");
FILE * fp = popen(command, "r");
if (!fp) { //validate file is open
return NULL;
}
while (fgets(path, sizeof(path) - 1, fp) != NULL) {
debug("in Primary While Loop");
fflush(stdout);
printf("the solution: %s", path);
if (strstr(path, ".") > strstr(path, "with absolute error") || strstr(path, ".5 ") != NULL) {
printf("answer was accepted");
}
}
}
}
int main() {
int arrayIndexes = 0;
int ** myArray = malloc(1 * sizeof( * myArray));
for (int a = 0; a < 10; a++) {
for (int b = 0; b < 10; b++) {
for (int c = 0; c < 10; c++) {
for (int d = 0; d < 10; d++) {
for (int e = 0; e < 10; e++) {
for (int f = 0; f < 10; f++) {
myArray[arrayIndexes] = malloc(6 * sizeof(int));
myArray[arrayIndexes][0] = a;
myArray[arrayIndexes][1] = b;
myArray[arrayIndexes][2] = c;
myArray[arrayIndexes][3] = d;
myArray[arrayIndexes][4] = e;
myArray[arrayIndexes][5] = f;
if (arrayIndexes > 0) {
for (int i = 0; i < arrayIndexes; i++) {
generateContentForSystems(myArray[arrayIndexes], myArray[i]);
}
}
++arrayIndexes;
myArray = realloc(myArray, (arrayIndexes + 1) * sizeof( * myArray));
}
}
}
}
}
}
for (int n = 0; n = arrayIndexes; n++) {
free(myArray[n]);
}
free(myArray);
return 0;
}
Your number strings are not long enough:
char numx[1];
char numy[1];
char numz[1];
char numx_2[1];
char numy_2[1];
char numz_2[1];
A string consists of a sequence of characters plus a null terminating byte. So even a single digit needs an array size of at least 2. When you use sprintf to write the text representation of a number to one of these arrays you write past the end of the array. This invokes undefined behavior.
These arrays need to be large enough to accommodate whatever value you may pass in, including a negation sign if needed.
char numx[10];
char numy[10];
char numz[10];
char numx_2[10];
char numy_2[10];
char numz_2[10];

fscanf() in C - need help reading a file using pointer notation

Spent an hour or two trying to debug this, but cannot figure out why it won't read my file correctly.
FILE *input;
int numAccounts = 7;
char **accountNames = malloc(sizeof(char)*numAccounts*10);
int *accountNumbers = malloc(sizeof(int)*numAccounts);
float *accountValues = malloc(sizeof(float)*numAccounts);
char *fileName = malloc(sizeof(char)*20);
input=fopen("input.txt","r");
int i;
for(i=0;i<numAccounts;i++) {
fscanf(input,"%s%d%f",*(accountNames+i),accountNumbers+i,accountValues+i);
printf("\n%s %d %f", *(accountNames+i), *(accountNumbers+i), *(accountValues+i));
}
fclose(input);
return 0;
And here is input.txt
Brown 1435 234.55
Dunn 2091 2011.75
Smith 8766 945.05
Stone 4530 0.0
Becker 9073 6235.75
Rich 1003 -42.00
Doe 6739 3655.80
Thank you!
You should start with non-dynamic allocation,
int main()
{
FILE *input = NULL;
int numAccounts = 7;
char accountNames[20] = "";
int accountNumbers = 0;
float accountValues = 0;
input=fopen("input.txt","r");
int i;
for(i=0;i<numAccounts;i++)
{
fscanf(input,"%s %d %f",accountNames,&accountNumbers,&accountValues);
printf("\n%s %d %f\n", accountNames, accountNumbers, accountValues);
}
fclose(input);
return 0;
}
If you must do dynamic allocation, then this pointer-to-pointer to char allocation is incorrect:
char **accountNames = malloc(sizeof(char)*numAccounts*10);
You'd need to allocate numAccounts of char * first, then for each char *, allocate 10 char. That can be done as follows:
char **accountNames = malloc(sizeof(char*)*numAccounts); // allocate numAccounts of char *
int i;
for( i=0; i < numAccounts; i++ )
{
*(accountNames + i) = malloc(sizeof(char)*10); // allocate 10 of char
}
So this should work:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *input = NULL;
int numAccounts = 7;
char **accountNames = malloc(sizeof(char*)*numAccounts); // allocate numAccounts of char *
int i;
for( i=0; i < numAccounts; i++ )
{
*(accountNames + i) = malloc(sizeof(char)*10); // allocate 10 of char
}
int *accountNumbers = malloc(sizeof(int)*numAccounts);
float *accountValues = malloc(sizeof(float)*numAccounts);
input=fopen("input.txt","r");
for(i=0; i<numAccounts; i++)
{
fscanf(input,"%s%d%f",*(accountNames+i), accountNumbers+i, accountValues+i);
printf("\n%s %d %f", *(accountNames+i), *(accountNumbers+i), *(accountValues+i));
}
fclose(input);
return 0;
}
If the account values are currency. You may want to save them as ints and divide by the lowest unity of that currency.
So instead of saving float accountValue = 23.25 as 23.25, save it as 2335 (23.25 * 100).
Then when you read it divide by 100 to get that value back.
float accountValueDollars;
int accountValueInCents;
fscanf(..., &accountValueInCents);
accountValueDollars = accountValueInCents / 100;
Also, you may want to consider saving in binary format, this way you don't have to worry about parsing the text.
typedef struct _account_t{
char name[50];
int account_number;
double amount;
} account_t;
int how_many = 0;
account_t * accounts = NULL;
// error checking skipped
fread(&how_many, 1, sizeof(int), input);
accounts = (account_t*)malloc(sizeof(account_t) * how_many);
for(int i = 0; i < how_many; i++){
fread(&accounts[i], 1, sizeof(account_t), input);
// print here or whatever
}
fclose(input);
NOTE: Untested code.

Having trouble with my binary search in C

I am having trouble with a binary search on strings in c. I use the strcmp function to compare the strings, but I still get no output when I type in a name that I know is in the list.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING_LEN 25
void insert_sata(char **strings, const char* filename, int size);
void allocate( char ***strings, int size);
int binary_search(char **strings, char *target, int start_idx, int end_idx);
int main(int argc, char* argv[]){
if(argc != 4){
printf("Wrong number of args");
}
char **pointer;
int size = atoi(argv[1]);
allocate(&pointer, size);
insert_data(pointer, argv[2], size);
int x;
int z = 1;
char search_name[MAX_STRING_LEN];
while( z == 1){
printf("\nEnter a name to search for: ");
scanf("%s", search_name);
x = binary_search(pointer, search_name, 0, size);
printf("\nContinue searching names? ( 1 = yes, 0 = No):");
scanf("%d", &z);
}
}
void allocate(char ***strings, int size){
int i;
*strings = malloc(sizeof(**strings) * size);
for( i = 0; i < size; i++)
{
(*strings)[i] = malloc(sizeof(char) * MAX_STRING_LEN);
}
}
void insert_data(char **strings, const char* filename, int size){
FILE *input;
input = fopen(filename, "r");
int i;
for (i = 0; i < size; i++){
fscanf(input,"%24s", strings[i]);
}
fclose(input);
}
int binary_search(char **strings, char *target, int start_idx, int end_idx){
int result;
int mid_idx = 0;
while( end_idx >= start_idx){
mid_idx = (end_idx + start_idx) / 2;
result = strcmp(strings[mid_idx], target);
if(result > 0){
end_idx = start_idx - 1;
}
else if (result < 0){
start_idx = mid_idx + 1;
}
else if( result == 0){
printf("%s was found in the set", target);
}
}
}
The binary search is the function that is giving me trouble. I do not recieve any seg faults or anything, just nothing is displayed when I search a name that is in the file. Here is the list of names that I scan into the program.
matt
susan
mark
david
aden
phil
erik
john
caden
mycah
Your input list isn't sorted and your program doesn't seem to try to sort it. Suppose you look for 'susan' - first comparision is 'susan' to 'aden', and the search area gets narrowed to last 5 items, while 'susan' is at the second position......
This:
if (result > 0) {
end_idx = start_idx - 1;
}
is probably mean to be:
if (result > 0) {
end_idx = mid_idx - 1;
}
The binary search algorithm requires that the list is sorted. Your example list isn't, so the algorithm will not work

Resources