配列とポインタ2

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
てる

配列とポインタ2

#1

投稿記事 by てる » 12年前

引き続き学校の課題で、"Tokyo", "Yokohama", "Osaka", "Nagoya", "Sapporo", "Toyonaka", "Kobe"をアルファベット順に並び替えて表示せよ。ただしi番目とj番目を入れ替えるvoid swap(char *name[], int i, int j)関数を自分でつくり使用せよ。

という課題が出てプログラムをつくってみました。
しかし、コンパイルは通ったのですがセグメンテーション違反が出ます・・・
swap関数とwhile文の中にprintfを入れて確認したところ、どうやらswap関数の中がおかしいみたいです。
いろいろ調べてみたのですがわからないので、よろしければご教授ください!
もしそれ以外にもおかしいところがあれば教えていただけると助かります。

コード:

#include <stdio.h>
#include <string.h>

void swap(char *name[], int i, int j){  
  
  char temp[10];
  strcpy(temp, name[i]);
  strcpy(name[i], name[j]);
  strcpy(name[j], temp);

}

int main(void){

  char *name[] = {"Tokyo", "Yokohama", "Osaka", "Nagoya", "Sapporo", "Toyonaka", "Kobe", NULL};
  int i = 1;
  int j = 1;
  int k = 0;

  while(name[i] != NULL){
    while(name[j] != NULL){
      if(strcmp(name[j-1], name[j]) > 0){
      swap(name, j-1, j);
      }
      j++;
    }
    i++;
  }

   while(name[k] != NULL){
     printf("%s\n", name[j]);
     k++;
   }

  return 0;
}

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: 配列とポインタ2

#2

投稿記事 by bitter_fox » 12年前

てる さんが書きました: swap関数とwhile文の中にprintfを入れて確認したところ、どうやらswap関数の中がおかしいみたいです。
もしそれ以外にもおかしいところがあれば教えていただけると助かります。
てる さんが書きました:

コード:

  int i = 1;
  int j = 1;

  while(name[i] != NULL){
    while(name[j] != NULL){
      if(strcmp(name[j-1], name[j]) > 0){
      swap(name, j-1, j);
      }
      j++;
    }
    i++;
  }
iとjが増え続けて範囲外を参照してしまいます。
ループ毎に初期化してください。
てる さんが書きました:

コード:

  int k = 0;

   while(name[k] != NULL){
     printf("%s\n", name[j]);
     k++;
   }
この状況でname[j]はおかしいです。
てる さんが書きました:

コード:

void swap(char *name[], int i, int j){  
  
  char temp[10];
  strcpy(temp, name[i]);
  strcpy(name[i], name[j]);
  strcpy(name[j], temp);

}

  char *name[] = {"Tokyo", "Yokohama", "Osaka", "Nagoya", "Sapporo", "Toyonaka", "Kobe", NULL};
nameは文字列リテラルの配列です。またname[n]は文字列リテラルです。
文字列リテラルの書き換えは処理系依存ですのでstrcpy(name, name[j])のような処理はよろしくありません。
http://www9.plala.or.jp/sgwr-t/c/sec10-3.html

文字列リテラルのアドレスを入れ替えてください。

てる

Re: 配列とポインタ2

#3

投稿記事 by てる » 12年前

ありがとうございます!
こういうことでしょうか?

コード:

void swap(char *name[], int i, int j){  
  
  char temp1[10];
  char temp2[10];
  strcpy(temp1, name[i]);
  strcpy(temp2, name[j]);
  strcpy(name[i], temp2);
  strcpy(name[j], temp1);

}

non
記事: 1097
登録日時: 13年前

Re: 配列とポインタ2

#4

投稿記事 by non » 12年前

>こういうことでしょうか?

うまくいかないことは、実行したらわかるでしょ。

文字列の中身を入れ替えるのではなく、name[]で覚えているアドレスを入れ替えます。
 char *tmp;
を用意します。後は、考えてみて。
non

閉鎖

“C言語何でも質問掲示板” へ戻る